基于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著作权归作者所有

相关推荐
疏狂难除11 分钟前
基于SeaORM+MySQL+Tauri2+Vite+React等的CRUD交互项目
前端·react.js·前端框架
onejason13 分钟前
如何使用PHP爬虫获取Shopee(虾皮)商品详情?
java·前端
赵大仁16 分钟前
深入解析前后端分离架构:原理、实践与最佳方案
前端·架构
学不动学不明白20 分钟前
PC端项目兼容手机端
前端
无名之逆20 分钟前
Hyperlane:轻量、高效、安全的 Rust Web 框架新选择
开发语言·前端·后端·安全·rust·github·ssl
wkj00127 分钟前
js给后端发送请求的方式有哪些
开发语言·前端·javascript
最新资讯动态34 分钟前
“RdbStore”上线开源鸿蒙社区 助力鸿蒙应用数据访问效率大幅提升
前端
magic 24535 分钟前
JavaScript运算符与流程控制详解
开发语言·前端·javascript
xulihang1 小时前
在手机浏览器上扫描文档并打印
前端·javascript·图像识别
RR91 小时前
【Vue3 进阶👍】:如何批量导出子组件的属性和方法?从手动代理到Proxy的完整指南
前端·vue.js