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

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15584.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能学习(七)之神经网络

目录 一、引言 二、经典神经网络回顾 &#xff08;一&#xff09;结构与计算过程 &#xff08;二&#xff09;局限性 三、循环神经网络&#xff08;RNN&#xff09;原理 &#xff08;一&#xff09;基本结构 &#xff08;二&#xff09;计算过程 &#xff08;三&#xf…

在Java中操作Redis

4.在Java中操作Redis 4.1 Redis的Java客户端 前面我们讲解了Redis的常用命令&#xff0c;这些命令是我们操作Redis的基础&#xff0c;那么我们在java程序中应该如何操作Redis呢&#xff1f;这就需要使用Redis的Java客户端&#xff0c;就如同我们使用JDBC操作MySQL数据库一样。…

大语言模型需要的可观测性数据的关联方式

可观测性数据的关联方式及其优缺点 随着现代分布式架构和微服务的普及&#xff0c;可观测性&#xff08;Observability&#xff09;已经成为确保系统健康、排查故障、优化性能的重要组成部分。有效的可观测性数据关联方式不仅能够帮助我们实时监控系统的运行状态&#xff0c;还…

棱光PDF工具箱:一站式解决你的各种需要

今天为大家介绍一款非常实用且完全免费的PDF工具箱——棱光PDF工具箱。它功能强大&#xff0c;操作简单&#xff0c;能够满足你对PDF文件的各种处理需求&#xff0c;包括添加水印、去除水印、批量转换格式等&#xff0c;绝对值得推荐&#xff01; 棱光PDF工具箱 棱光PDF工具箱…

Docker安装Redis

一、保证Docker提起来了 systemctl status docker想这没有启动要先启动一下 systemctl status docke二、拉取Redis&#xff08;默认拉最新版&#xff09; sudo docker pull redis检查一下拉成功没有 docker images三、创建相关目录 mkdir -p /home/redis/{conf,data}四、…

云原生(五十四) | RDS数据导入与导出

文章目录 RDS数据导入与导出 一、导入场景说明 二、RDS数据导入实现 三、导出场景说明 四、RDS数据导出实现 RDS数据导入与导出 一、导入场景说明 思考&#xff1a;我们刚才的操作都是通过SQL语句实现的&#xff0c;如果我们要导入的文件是以SQL、CSV或Excel等形式存储&…

如何使用DeepSeek帮助自己的工作?

最近众多大模型爆火,如日中天的,莫过于最近的DeepSeek了,那么怎么去利用它帮助我们的工作呢? 代码生成与优化 快速生成代码:程序员可以直接通过自然语言描述功能需求,让 DeepSeek 生成相应的代码。比如需要实现一个用 Python 编写的计算斐波那契数列的函数,只需简单描述…

Python Pandas(3):DataFrame

1 介绍 DataFrame 是 Pandas 中的另一个核心数据结构&#xff0c;类似于一个二维的表格或数据库中的数据表。它含有一组有序的列&#xff0c;每列可以是不同的值类型&#xff08;数值、字符串、布尔型值&#xff09;。DataFrame 既有行索引也有列索引&#xff0c;它可以被看做由…

防火墙术语大全( Firewalld Glossary of Terms)

防火墙术语大全 防火墙作为网络安全中不可或缺的设备&#xff0c;在各种网络架构中扮演着至关重要的角色。无论是企业级防火墙、云防火墙还是家用路由器内置的防火墙&#xff0c;它们的工作原理和配置策略都离不开一系列专业术语的支撑。对于网络工程师来说&#xff0c;掌握这…

Web前端开发--HTML

HTML快速入门 1.新建文本文件&#xff0c;后缀名改为.html 2.编写 HTML结构标签 3.在<body>中填写内容 HTML结构标签 特点 1.HTML标签中不区分大小写 2.HTML标签属性值中可以使用单引号也可使用双引号 3.HTML语法结构比较松散&#xff08;但在编写时要严格一点&…

深度整理总结MySQL——MySQL加锁工作原理

MySQL加锁工作原理 前言前置知识- 锁为什么加在索引上锁的粒度优化提高并发性避免全表扫描优化死锁处理解决幻读问题 什么SQL语句会加行级锁MySQL是如何加行级锁场景模拟代码唯一索引等值查询退化为记录锁为什么会退化为记录锁分析加了什么锁为什么会退化为间隙锁为什么我可以插…

2.10日学习总结

题目一&#xff1a; AC代码 #include <stdio.h>#define N 1000000typedef long long l;int main() {int n, m;l s 0;l a[N 1], b[N 1];int i 1, j 1;scanf("%d %d", &n, &m);for (int k 1; k < n; k) {scanf("%lld", &a[k]);…

Spring Boot Actuator(官网文档解读)

定义 Spring Boot Actuator 是 Spring Boot 提供的一个用于监控和管理应用程序的模块。它能够提供各种生产级别的功能&#xff0c;如健康检查、度量指标收集、配置属性查看等&#xff0c;帮助开发者了解应用的内部状态并进行故障排查。 Actuator 引入 要启用 Actuator…

如何实现图片式按钮的功能

文章目录 1. 概念介绍2. 使用方法2.1 filled风格2.2 filledTonal风格2.3 outlined风格 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何修改NavigationBar组件的形状"相关的内容&#xff0c;本章回中将介绍IconButtion组件.闲话休提…

[LLM面试题] 指示微调(Prompt-tuning)与 Prefix-tuning区别

一、提示调整(Prompt Tuning) Prompt Tuning是一种通过改变输入提示语&#xff08;input prompt&#xff09;以获得更优模型效果的技术。举个例子&#xff0c;如果我们想将一条英语句子翻译成德语&#xff0c;可以采用多种不同的方式向模型提问&#xff0c;如下图所示&#xf…

2月10日QT

作业> 将文本编辑器功能完善 include "widget.h" #include "ui_widget.h" #include <QMessageBox> //消息对话框类 #include <QFontDialog> //字体类对话框 #include <QFont> //字体类 #include <QColorDialog> //颜…

安卓开发,底部导航栏

1、创建导航栏图标 使用系统自带的矢量图库文件&#xff0c;鼠标右键点击res->New->Vector Asset 修改 Name , Clip art 和 Color 再创建一个 同样的方法再创建四个按钮 2、添加百分比布局依赖 app\build.gradle.kts 中添加百分比布局依赖&#xff0c;并点击Sync Now …

Spring Boot中实现多租户架构

文章目录 Spring Boot中实现多租户架构多租户架构概述核心思想多租户的三种模式优势挑战租户识别机制1. 租户标识(Tenant Identifier)2. 常见的租户识别方式3. 实现租户识别的关键点4. 租户识别示例代码5. 租户识别机制的挑战数据库隔离的实现1. 数据库隔离的核心目标2. 数据…

《LeetCode Hot100》 Day01

Day01 轮转数组 思路&#xff1a; &#xff08;1&#xff09; 使用O(1) 空间复杂度解决&#xff0c;就需要原地解决&#xff0c;不能创建新的数组。 &#xff08;2&#xff09; 先整体反转数组&#xff0c;再反转前k个数&#xff0c;再反转剩下的数。即可完整本题。 &…

【python】matplotlib(animation)

文章目录 1、matplotlib.animation1.1、FuncAnimation1.2、修改 matplotlib 背景 2、matplotlib imageio2.1、折线图2.2、条形图2.3、散点图 3、参考 1、matplotlib.animation 1.1、FuncAnimation matplotlib.animation.FuncAnimation 是 Matplotlib 库中用于创建动画的一个…