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

相关推荐
程序员小续27 分钟前
现代前端工程化实践:高效构建的秘密
开发语言·前端·javascript·vue.js·webpack·前端框架·ecmascript
RickZhou30 分钟前
React 个人博客 支持自定义主题
前端
林啾啾35 分钟前
按钮凸起与按下css效果
前端·css
年纪轻轻只想躺平36 分钟前
scss模块化
前端·css·scss
浪浪山小白兔37 分钟前
CSS 实现下拉菜单效果实例解析
前端·css
世间一剑40 分钟前
轻松理解CSS中的float浮动元素
前端·css
大模型铲屎官41 分钟前
从基础到进阶,掌握 CSS 变量与calc()函数的完整指南
前端·css·html·css3·html5·css变量·calc函数
fury_12341 分钟前
css:怎么设置图片不变形
前端·css
Giser_轩43 分钟前
番外02:前端八股文面试题-CSS篇
前端·css
禁默1 小时前
HTML中的图片标签详解及路径使用【学术投稿-第五届环境资源与能源工程国际学术会议(ICEREE 2025)】
网络·html·能源