基于html写一个音乐动态爱心盒子有音乐和导航基本功能实现
基于html写一个音乐动态爱心盒子有音乐和导航基本功能实现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>3D爱心盒子</title>
<style>
:root {
--cube-size: min(200px, 50vw);
--font-size-large: min(2em, 5vw);
--font-size-medium: min(16px, 4vw);
--font-size-small: min(14px, 3.5vw);
--spacing: min(20px, 5vw);
--border-radius: min(20px, 4vw);
}
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
perspective: 1000px;
overflow: hidden;
position: relative;
}
.background-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
overflow: hidden;
}
.background-image {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
animation: zoomEffect 20s infinite alternate;
opacity: 0;
transition: opacity 1.5s ease-in-out;
transform-origin: center center;
will-change: transform, opacity;
filter: brightness(0.7); /* 稍微调暗背景,让前景更突出 */
}
@keyframes zoomEffect {
0% { transform: scale(1); }
100% { transform: scale(1.1); }
}
.cube {
width: var(--cube-size);
height: var(--cube-size);
position: relative;
transform-style: preserve-3d;
animation: none; /* 初始状态停止动画 */
}
.cube-container {
position: relative;
perspective: 1000px;
width: var(--cube-size);
height: var(--cube-size);
z-index: 1;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
padding: calc(var(--spacing) * 0.8);
border-radius: var(--border-radius);
opacity: 0;
transform: scale(0);
transition: all 0.8s;
}
.face {
position: absolute;
width: var(--cube-size);
height: var(--cube-size);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-large);
color: white;
background: rgba(255, 255, 255, 0.1);
border: 2px solid white;
backdrop-filter: blur(5px);
box-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
text-shadow: 0 0 10px #fff;
font-family: Arial, sans-serif;
transition: all 0.3s;
backface-visibility: visible;
}
.face:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.1);
}
.front { transform: translateZ(calc(var(--cube-size) * 0.5)); }
.back { transform: rotateY(180deg) translateZ(calc(var(--cube-size) * 0.5)); }
.right { transform: rotateY(90deg) translateZ(calc(var(--cube-size) * 0.5)); }
.left { transform: rotateY(-90deg) translateZ(calc(var(--cube-size) * 0.5)); }
.top { transform: rotateX(90deg) translateZ(calc(var(--cube-size) * 0.5)); }
.bottom { transform: rotateX(-90deg) translateZ(calc(var(--cube-size) * 0.5)); }
@keyframes rotate {
0% {
transform: rotateY(0) rotateX(0) rotateZ(0);
}
100% {
transform: rotateY(360deg) rotateX(360deg) rotateZ(360deg);
}
}
.hearts {
position: fixed;
width: 100%;
height: 100%;
pointer-events: none;
}
.heart {
position: absolute;
font-size: 20px;
animation: fall linear;
}
@keyframes fall {
to {
transform: translateY(100vh);
}
}
.loading {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 24px;
z-index: 1000;
background: rgba(0, 0, 0, 0.7);
padding: 20px;
border-radius: 10px;
display: none;
}
.gift-wrap {
position: relative;
width: var(--cube-size);
height: var(--cube-size);
cursor: pointer;
transform-style: preserve-3d;
transition: transform 1s;
}
.gift-box {
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(45deg, #ff69b4, #ff1493);
border: 4px solid #fff;
box-shadow: 0 0 30px rgba(255, 20, 147, 0.5);
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: white;
text-shadow: 0 0 10px #fff;
transform-origin: center;
transition: all 0.8s;
}
.gift-box::before {
content: '';
position: absolute;
width: 20px;
height: 100%;
background: rgba(255, 255, 255, 0.5);
left: 50%;
transform: translateX(-50%);
}
.gift-box::after {
content: '';
position: absolute;
width: 100%;
height: 20px;
background: rgba(255, 255, 255, 0.5);
top: 50%;
transform: translateY(-50%);
}
.opened .gift-box {
transform: scale(0);
opacity: 0;
}
.opened .cube-container {
opacity: 1;
transform: scale(1);
}
.click-hint {
position: absolute;
bottom: -40px;
left: 50%;
transform: translateX(-50%);
color: white;
font-size: 16px;
text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { opacity: 0.5; transform: translateX(-50%) scale(0.95); }
50% { opacity: 1; transform: translateX(-50%) scale(1.05); }
100% { opacity: 0.5; transform: translateX(-50%) scale(0.95); }
}
.opened .cube {
animation: rotate 10s infinite linear; /* 打开后开始动画 */
}
.controls {
position: fixed;
top: 20px;
right: 20px;
display: flex;
gap: 10px;
z-index: 1000;
}
.control-btn {
background: rgba(255, 255, 255, 0.2);
border: 2px solid white;
color: white;
padding: calc(var(--spacing) * 0.5) var(--spacing);
border-radius: 20px;
cursor: pointer;
backdrop-filter: blur(5px);
transition: all 0.3s;
font-size: var(--font-size-small);
display: flex;
align-items: center;
gap: 5px;
}
.control-btn:hover {
background: rgba(255, 255, 255, 0.4);
transform: scale(1.05);
}
.control-btn i {
font-size: 20px;
}
.music-player {
position: fixed;
bottom: 40px;
left: 20px;
background: rgba(255, 255, 255, 0.2);
padding: calc(var(--spacing) * 0.5);
border-radius: 20px;
backdrop-filter: blur(5px);
display: flex;
align-items: center;
gap: 10px;
z-index: 1000;
border: 2px solid white;
font-size: var(--font-size-small);
}
.music-controls {
display: flex;
align-items: center;
gap: 10px;
}
.music-info {
color: white;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
font-size: var(--font-size-small);
}
.paused .cube {
animation-play-state: paused;
}
.nav-buttons {
position: fixed;
top: var(--spacing);
left: 50%;
transform: translateX(-50%);
display: flex;
gap: calc(var(--spacing) * 0.5);
flex-wrap: wrap;
justify-content: center;
width: 90%;
padding: calc(var(--spacing) * 0.5);
z-index: 1000;
}
.nav-btn {
background: rgba(255, 255, 255, 0.2);
border: 1px solid white;
color: white;
padding: calc(var(--spacing) * 0.4) calc(var(--spacing) * 0.8);
border-radius: 20px;
cursor: pointer;
font-size: var(--font-size-small);
transition: all 0.3s;
backdrop-filter: blur(5px);
white-space: nowrap;
}
.nav-btn:hover {
background: rgba(255, 255, 255, 0.3);
}
.nav-btn.active {
background: rgba(255, 255, 255, 0.4);
}
/* 为每个页面内容添加样式 */
.page-content {
position: absolute;
width: 100%;
height: 100%;
display: none;
align-items: center;
justify-content: center;
color: white;
font-size: 1.5em;
text-align: center;
opacity: 0;
transition: opacity 0.5s;
}
.page-content.active {
display: flex;
opacity: 1;
}
/* 媒体查询适应不同设备 */
@media (max-width: 768px) {
.controls {
top: auto;
bottom: calc(var(--spacing) * 3);
right: var(--spacing);
}
.music-player {
bottom: 50px;
left: var(--spacing);
}
.nav-buttons {
top: calc(var(--spacing) * 0.5);
}
}
@media (max-height: 600px) {
:root {
--cube-size: min(150px, 40vh);
}
.nav-buttons {
position: fixed;
right: var(--spacing);
top: 50%;
transform: translateY(-50%);
flex-direction: column;
left: auto;
width: auto;
}
}
/* 触摸设备优化 */
@media (hover: none) {
.face:hover {
transform: none;
}
.control-btn:active,
.nav-btn:active {
transform: scale(0.95);
}
}
/* 修复transform导致的闪烁问题 */
.cube, .face {
transform-style: preserve-3d;
backface-visibility: visible;
-webkit-backface-visibility: visible;
will-change: transform;
}
/* 修复移动端动画性能问题 */
@media (max-width: 768px) {
.cube {
animation-duration: 15s; /* 降低动画速度提升性能 */
}
.background-image {
animation: none; /* 移动端禁用背景动画 */
}
}
/* 添加加载状态样式 */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.loading-spinner {
width: 50px;
height: 50px;
border: 3px solid #fff;
border-radius: 50%;
border-top-color: transparent;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* 添加版权信息样式 */
.copyright {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 8px;
font-size: var(--font-size-small);
z-index: 1000;
border-top: 1px solid rgba(255, 255, 255, 0.2);
}
.copyright a {
color: #ff69b4;
text-decoration: none;
transition: color 0.3s;
}
.copyright a:hover {
color: #ff1493;
}
.music-player {
min-width: 200px;
padding: calc(var(--spacing) * 0.8);
}
.music-controls {
display: flex;
align-items: center;
gap: 15px;
}
.music-info {
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 10px;
}
.music-title {
font-weight: bold;
margin-bottom: 3px;
}
.music-artist {
font-size: 0.9em;
opacity: 0.8;
}
.music-btn {
background: none;
border: none;
color: white;
cursor: pointer;
padding: 5px;
font-size: 16px;
opacity: 0.8;
transition: all 0.3s;
}
.music-btn:hover {
opacity: 1;
transform: scale(1.1);
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<!-- 添加预加载提示 -->
<link rel="preconnect" href="https://cdnjs.cloudflare.com">
<link rel="preconnect" href="https://source.unsplash.com">
<link rel="preconnect" href="https://music.163.com">
<link rel="dns-prefetch" href="https://music.163.com">
</head>
<body>
<div class="loading-overlay">
<div class="loading-spinner"></div>
<div style="color: white; margin-top: 20px;">加载中...</div>
</div>
<div class="loading">加载中...</div>
<div class="background-container">
<img class="background-image" src="https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/156/156-bigskin-1.jpg" alt="张良-死亡颂唱者">
<img class="background-image" src="https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/141/141-bigskin-1.jpg" alt="貂蝉-绝代芳华">
<img class="background-image" src="https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/157/157-bigskin-1.jpg" alt="不知火舞-魅语">
</div>
<div class="controls">
<button class="control-btn" id="rotateToggle">
<i class="fas fa-sync-alt"></i> 暂停旋转
</button>
</div>
<div class="nav-buttons">
<button class="nav-btn active" data-page="love">我们的爱</button>
<button class="nav-btn" data-page="forever">爱你一万年</button>
<button class="nav-btn" data-page="heart">愿得一人心</button>
</div>
<div class="music-player">
<div class="music-controls">
<button class="music-btn" id="prevMusic">
<i class="fas fa-step-backward"></i>
</button>
<button class="control-btn" id="playMusic">
<i class="fas fa-play"></i>
</button>
<button class="music-btn" id="nextMusic">
<i class="fas fa-step-forward"></i>
</button>
</div>
<div class="music-info">
<div class="music-title">加载中...</div>
<div class="music-artist"></div>
</div>
</div>
<div class="gift-wrap">
<div class="gift-box">
<span>💝</span>
</div>
<div class="cube-container">
<div class="cube">
<div class="face front">我爱你</div>
<div class="face back">Love You</div>
<div class="face right">永远爱</div>
<div class="face left">想你了</div>
<div class="face top">最爱你</div>
<div class="face bottom">爱你哦</div>
</div>
</div>
<div class="click-hint">点击打开礼物</div>
</div>
<div class="hearts"></div>
<script>
function createHeart() {
const heart = document.createElement('div');
heart.className = 'heart';
heart.innerHTML = ['❤', '💖', '💗', '💓'][Math.floor(Math.random() * 4)];
const giftWrap = document.querySelector('.gift-wrap');
const giftRect = giftWrap.getBoundingClientRect();
const startX = giftRect.left + giftRect.width / 2;
const startY = giftRect.top + giftRect.height / 2;
heart.style.left = startX + 'px';
heart.style.top = startY + 'px';
heart.style.animationDuration = Math.random() * 3 + 2 + 's';
heart.style.opacity = Math.random();
heart.style.color = `hsl(${Math.random() * 60 + 330}, 100%, 50%)`;
heart.style.fontSize = Math.random() * 10 + 15 + 'px';
document.querySelector('.hearts').appendChild(heart);
heart.addEventListener('animationend', () => heart.remove());
}
// 性能优化:使用节流函数处理心形创建
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
// 优化的创建心形函数
const throttledCreateHeart = throttle(createHeart, 100);
setInterval(throttledCreateHeart, 300);
// 改进的背景图片处理
const images = document.querySelectorAll('.background-image');
let currentImage = 0;
let imagesLoaded = 0;
const loadingElement = document.querySelector('.loading');
// 图片加载处理
function handleImageLoad() {
imagesLoaded++;
if (imagesLoaded === images.length) {
loadingElement.style.display = 'none';
startImageRotation();
}
}
// 替换背景图片数组
const heroImages = [
{
url: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/156/156-bigskin-1.jpg',
backup: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/156/156-bigskin-2.jpg'
},
{
url: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/141/141-bigskin-1.jpg',
backup: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/141/141-bigskin-3.jpg'
},
{
url: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/157/157-bigskin-1.jpg',
backup: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/157/157-bigskin-2.jpg'
},
{
url: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/154/154-bigskin-1.jpg',
backup: 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/154/154-bigskin-3.jpg'
}
];
// 修改图片加载错误处理
function handleImageError(img) {
const currentSrc = img.src;
const heroImage = heroImages.find(hero => hero.url === currentSrc);
if (heroImage) {
img.src = heroImage.backup;
} else {
// 如果备用图也加载失败,使用默认图片
img.src = 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/149/149-bigskin-1.jpg';
}
}
// 优化的图片切换函数
function startImageRotation() {
images[0].style.opacity = '1';
let lastChange = Date.now();
const CHANGE_INTERVAL = 5000; // 5秒切换一次
function changeBackground() {
const now = Date.now();
if (now - lastChange < CHANGE_INTERVAL) return;
images[currentImage].style.opacity = '0';
currentImage = (currentImage + 1) % images.length;
images[currentImage].style.opacity = '1';
lastChange = now;
}
// 使用requestAnimationFrame代替setInterval
function animate() {
changeBackground();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}
// 优化图片预加载函数
async function preloadImages() {
const promises = heroImages.map(hero => {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => {
// 如果主图失败,尝试加载备用图
img.src = hero.backup;
};
img.src = hero.url;
});
});
try {
await Promise.race([
Promise.all(promises),
new Promise((resolve) => setTimeout(resolve, 3000)) // 3秒超时
]);
} catch (error) {
console.error('图片预加载失败:', error);
}
}
// 在初始化函数中添加预加载调用
const originalInit = init;
init = async function() {
await preloadImages();
originalInit();
};
// 添加页面可见性处理
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
// 页面不可见时暂停动画
document.body.classList.add('paused');
} else {
document.body.classList.remove('paused');
}
});
// 添加礼物盒点击事件
const giftWrap = document.querySelector('.gift-wrap');
giftWrap.addEventListener('click', function() {
if (!this.classList.contains('opened')) {
this.classList.add('opened');
// 播放音效(可选)
const audio = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-magical-sparkle-sound-2270.mp3');
audio.play().catch(e => console.log('无法播放音效'));
// 点击时创建更多心形
for(let i = 0; i < 20; i++) {
setTimeout(createHeart, i * 50);
}
}
});
// 添加旋转控制
const rotateToggle = document.getElementById('rotateToggle');
const cube = document.querySelector('.cube');
let isRotating = true;
rotateToggle.addEventListener('click', () => {
isRotating = !isRotating;
if (isRotating) {
cube.style.animationPlayState = 'running';
rotateToggle.innerHTML = '<i class="fas fa-sync-alt"></i> 暂停旋转';
} else {
cube.style.animationPlayState = 'paused';
rotateToggle.innerHTML = '<i class="fas fa-sync-alt"></i> 继续旋转';
}
});
// 添加音乐控制
const playMusic = document.getElementById('playMusic');
const audio = new Audio('https://music.163.com/song/media/outer/url?id=255859.mp3');
let isPlaying = false;
playMusic.addEventListener('click', () => {
if (isPlaying) {
audio.pause();
playMusic.innerHTML = '<i class="fas fa-play"></i>';
} else {
audio.play().then(() => {
playMusic.innerHTML = '<i class="fas fa-pause"></i>';
}).catch(error => {
console.error('播放失败:', error);
alert('音乐加载失败,请检查网络连接');
});
}
isPlaying = !isPlaying;
});
// 音乐循环播放
audio.loop = true;
// 监听音乐加载状态
audio.addEventListener('canplay', () => {
playMusic.disabled = false;
});
audio.addEventListener('error', () => {
alert('音乐加载失败,请检查网络连接');
playMusic.disabled = true;
});
// 页面关闭时停止音乐
window.addEventListener('beforeunload', () => {
audio.pause();
});
// 修改现有的页面可见性处理
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
if (isPlaying) {
audio.pause();
}
document.body.classList.add('paused');
} else {
if (isPlaying) {
audio.play();
}
document.body.classList.remove('paused');
}
});
// 添加导航按钮功能
const navButtons = document.querySelectorAll('.nav-btn');
const faces = document.querySelectorAll('.face');
const pageContents = {
love: [
'我爱你', 'Love You', '永远爱',
'想你了', '最爱你', '爱你哦'
],
forever: [
'一万年', '永恒爱', '真爱你',
'心相印', '天长地久', '爱相随'
],
heart: [
'一人心', '白首同', '执子手',
'与子偕老', '心心相印', '情深似海'
]
};
navButtons.forEach(button => {
button.addEventListener('click', () => {
// 更新按钮状态
navButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
// 简单地更新文字内容,不添加缩放动画
const page = button.dataset.page;
const contents = pageContents[page];
faces.forEach((face, index) => {
face.textContent = contents[index];
});
// 创建少量心形特效
for(let i = 0; i < 5; i++) {
setTimeout(createHeart, i * 200);
}
});
});
// 添加设备检测和优化
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
// 优化移动端触摸事件
if (isMobile) {
// 禁用双击缩放
document.addEventListener('touchstart', (e) => {
if (e.touches.length > 1) {
e.preventDefault();
}
}, { passive: false });
// 优化触摸创建心形效果
let lastTap = 0;
document.addEventListener('touchend', (e) => {
const currentTime = new Date().getTime();
const tapLength = currentTime - lastTap;
if (tapLength < 500 && tapLength > 0) {
e.preventDefault();
}
lastTap = currentTime;
});
}
// 监听屏幕方向变化
window.addEventListener('orientationchange', () => {
setTimeout(() => {
window.scrollTo(0, 0);
// 重新计算尺寸
const root = document.documentElement;
const size = Math.min(window.innerWidth * 0.5, window.innerHeight * 0.5, 200);
root.style.setProperty('--cube-size', `${size}px`);
}, 200);
});
// 优化背景图片加载
function loadOptimizedImage(img) {
const width = window.innerWidth;
const quality = width < 768 ? 70 : 90;
const size = width < 768 ? '800x600' : '1920x1080';
img.src = img.src.replace(/\d+x\d+/, size);
}
images.forEach(img => {
loadOptimizedImage(img);
});
// 添加全局错误处理
window.onerror = function(msg, url, line, col, error) {
console.error('Error: ', msg, url, line, col, error);
return false;
};
// 优化音乐加载和播放
function initAudio() {
const audioUrls = [
'https://music.163.com/song/media/outer/url?id=255859.mp3',
'https://api.uomg.com/api/rand.music?sort=热歌榜', // 备用音乐API
'https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3' // 第二个备用地址
];
let currentUrlIndex = 0;
const audio = new Audio();
function tryNextUrl() {
if (currentUrlIndex < audioUrls.length) {
audio.src = audioUrls[currentUrlIndex];
audio.load();
currentUrlIndex++;
} else {
console.error('所有音乐源都失败');
playMusic.disabled = true;
}
}
audio.addEventListener('error', tryNextUrl);
tryNextUrl(); // 开始尝试第一个URL
return audio;
}
// 替换图片加载代码
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => {
// 如果Unsplash失败,使用备用图片服务
if (url.includes('unsplash')) {
img.src = `https://picsum.photos/1920/1080?random=${Math.random()}`;
} else if (url.includes('picsum')) {
img.src = `https://source.lorem.space/1920x1080`; // 第二个备用服务
} else {
reject(new Error('Image load failed'));
}
};
img.src = url;
});
}
// 修改初始化函数
async function init() {
try {
document.querySelector('.loading-overlay').style.display = 'flex';
// 并行加载所有资源
const promises = [
// 预加载字体图标
new Promise((resolve) => {
const link = document.querySelector('link[href*="font-awesome"]');
if (link.complete) resolve();
link.onload = resolve;
link.onerror = resolve; // 即使加载失败也继续
}),
// 预加载背景图片
...Array.from(document.querySelectorAll('.background-image')).map(img =>
loadImage(img.src).then(loadedImg => {
img.src = loadedImg.src;
}).catch(console.error)
)
];
// 等待所有资源加载完成或超时
await Promise.race([
Promise.all(promises),
new Promise(resolve => setTimeout(resolve, 5000)) // 5秒超时
]);
} catch (error) {
console.error('加载出错:', error);
} finally {
// 无论如何都移除加载界面
document.querySelector('.loading-overlay').style.display = 'none';
startImageRotation();
// 延迟初始化音频,避免阻塞页面加载
setTimeout(() => {
const audio = initAudio();
// 重新绑定播放按钮事件
const playMusic = document.getElementById('playMusic');
playMusic.addEventListener('click', () => {
if (audio.paused) {
audio.play().then(() => {
playMusic.innerHTML = '<i class="fas fa-pause"></i>';
}).catch(err => {
console.error('播放失败:', err);
tryNextUrl();
});
} else {
audio.pause();
playMusic.innerHTML = '<i class="fas fa-play"></i>';
}
});
}, 1000);
}
}
// 添加页面重试机制
let retryCount = 0;
const maxRetries = 3;
function retryInit() {
if (retryCount < maxRetries) {
retryCount++;
console.log(`重试第${retryCount}次`);
init();
} else {
alert('页面加载失败,请刷新重试');
}
}
// 监听页面加载状态
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// 添加错误恢复机制
window.addEventListener('error', (event) => {
console.error('资源加载失败:', event.target);
if (event.target.tagName === 'IMG') {
handleImageError(event.target);
}
}, true);
// 修复触摸事件
let touchStartY = 0;
document.addEventListener('touchstart', (e) => {
touchStartY = e.touches[0].clientY;
}, { passive: true });
document.addEventListener('touchmove', (e) => {
const touchY = e.touches[0].clientY;
const diff = touchStartY - touchY;
if (Math.abs(diff) > 10) {
e.preventDefault(); // 防止滑动
}
}, { passive: false });
// 修复cube动画
function resetCubeAnimation() {
const cube = document.querySelector('.cube');
cube.style.animation = 'none';
cube.offsetHeight; // 触发重排
cube.style.animation = null;
}
// 在屏幕方向改变时重置动画
window.addEventListener('orientationchange', () => {
setTimeout(resetCubeAnimation, 300);
});
// 启动初始化
init();
// 添加音乐列表
const musicList = [
{
title: "老鼠爱大米",
artist: "香香",
url: "https://music.163.com/song/media/outer/url?id=255859.mp3"
},
{
title: "小酒窝",
artist: "林俊杰/蔡卓妍",
url: "https://music.163.com/song/media/outer/url?id=108478.mp3"
},
{
title: "最浪漫的事",
artist: "赵咏华",
url: "https://music.163.com/song/media/outer/url?id=276025.mp3"
},
{
title: "情非得已",
artist: "庾澄庆",
url: "https://music.163.com/song/media/outer/url?id=94639.mp3"
},
{
title: "爱的就是你",
artist: "王力宏",
url: "https://music.163.com/song/media/outer/url?id=112322.mp3"
},
{
title: "我们的爱",
artist: "F.I.R.",
url: "https://music.163.com/song/media/outer/url?id=357424.mp3"
},
{
title: "童话",
artist: "光良",
url: "https://music.163.com/song/media/outer/url?id=386538.mp3"
},
{
title: "爱情转移",
artist: "陈奕迅",
url: "https://music.163.com/song/media/outer/url?id=65528.mp3"
},
{
title: "月亮代表我的心",
artist: "邓丽君",
url: "https://music.163.com/song/media/outer/url?id=255858.mp3"
},
{
title: "暖暖",
artist: "梁静茹",
url: "https://music.163.com/song/media/outer/url?id=139723.mp3"
},
{
title: "给我一个理由忘记",
artist: "A-Lin",
url: "https://music.163.com/song/media/outer/url?id=209760.mp3"
},
{
title: "第一次爱的人",
artist: "王心凌",
url: "https://music.163.com/song/media/outer/url?id=255858.mp3"
}
];
let currentMusicIndex = 0;
// 修改音乐控制相关代码
function updateMusicInfo() {
const music = musicList[currentMusicIndex];
document.querySelector('.music-title').textContent = music.title;
document.querySelector('.music-artist').textContent = music.artist;
}
function playCurrentMusic() {
const music = musicList[currentMusicIndex];
audio.src = music.url;
audio.play().then(() => {
playMusic.innerHTML = '<i class="fas fa-pause"></i>';
updateMusicInfo();
}).catch(error => {
console.error('播放失败:', error);
playNextMusic(); // 如果当前音乐播放失败,尝试下一首
});
}
function playNextMusic() {
currentMusicIndex = (currentMusicIndex + 1) % musicList.length;
playCurrentMusic();
}
function playPrevMusic() {
currentMusicIndex = (currentMusicIndex - 1 + musicList.length) % musicList.length;
playCurrentMusic();
}
// 添加音乐控制事件监听
document.getElementById('prevMusic').addEventListener('click', playPrevMusic);
document.getElementById('nextMusic').addEventListener('click', playNextMusic);
// 修改原有的播放按钮事件
playMusic.addEventListener('click', () => {
if (audio.paused) {
playCurrentMusic();
} else {
audio.pause();
playMusic.innerHTML = '<i class="fas fa-play"></i>';
}
});
// 添加音乐结束自动播放下一首
audio.addEventListener('ended', playNextMusic);
// 初始化音乐信息
updateMusicInfo();
</script>
<div class="copyright">
Copyright © 2024 <a href="javascript:void(0)">星糖曙光</a>. All Rights Reserved.
</div>
</body>
</html>
前端csscss3
发布于2025-02-07著作权归作者所有