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

相关推荐
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
一只爱撸猫的程序猿4 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼4 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT5 小时前
promise & async await总结
前端
Jerry说前后端5 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化