亚伦影音工作室 发表于 2025-10-3 21:13

假如世界没有你

本帖最后由 亚伦影音工作室 于 2025-10-5 13:35 编辑 <br /><br /><style>
      #bj {position: relative;
            width: 1286px;
            height: 720px;
            margin-left: -300px;
            margin-top: 10px;
            overflow: hidden;z-index:12345;
            background:radial-gradient(ellipse farthest-corner at center center, transparent 38%,#000 90%),url(https://pic1.imgdb.cn/item/6862641f58cb8da5c87f852b.jpg),linear-gradient(135deg, #e56420, #c22525, #3d9c31, #000078);
      }
      
      
      #lyricsCanvas {
            position: absolute;
            top: 30%;
            left: 2%;
            width: 800px;
            height: 450px;
            z-index: 2;
            
      }
      
         
      .controls-containe{
            position: absolute;
            bottom: 30px;
            left: 10px;
            width: 100%;
            display: flex;
            justify-content: center;
      }
      
      .controls {
            width: 85%;
            display: flex;
            align-items: center;
            gap: 10px;
            z-index: 4;
      }
      
      #progress {position:relative;
            bottom: 8px;
            flex-grow: 1;
            width: 100%;
            height: 4px;
            -webkit-appearance: none;
            background-color: transparent;
            outline: none;
      }
   

#progress::-webkit-slider-container {
    height: 18px;border-radius: 20px;
    overflow: hidden;
}
#progress::-webkit-slider-runnable-track {
    height: 4px;border-radius: 20px;
    background: #EEE;
}
#progress::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 20px;
    background: #880000;
    border: 1px solid transparent;
    margin-top: -4px;
    border-image: linear-gradient(#880000,#880000) 0 fill / 4 11 4 0 / 0px 0px 0 2000px;
}

      .play-btn {
            width: 90px;
            height: 30px;
            background-size: contain;
            background-repeat: no-repeat;
            background-position: center;
            background-color: transparent;
            border: none;
            cursor: pointer;
font: 400 24px '华文隶书', sans-serif;
            
            color: #eee;
            display: flex;
            align-items: center;
            justify-content: center;
      }
      
      .time-display {
         font: 300 20px '华文隶书', sans-serif;
            color: #eee;
            min-width: 110px;
            text-align: center;
      }
      
   </style>

   
   <divid="bj">
    <canvas id="lyricsCanvas" width="850" height="450"></canvas>
      
    <div class="controls-containe">
                            <div class="controls">
                              <span id="playBtn" class="play-btn">暂停</span>
<input type="range" id="progress" min="0" max="100" value="0"></input>
                              <span id="timeDisplay" class="time-display">00:00 / 00:00</span>
                              
                            </div>
                        </div>
      
</div>
<audio id="audio" src="https://hs6.krakenfiles.com/uploads/03-10-2025/5fhsb3r441/music.m4a" autoplay loop></audio>
    <script>
      // 基础工具函数:时间格式化
      function formatTime(seconds) {
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins}:${secs < 10 ? '0' + secs : secs}`;
      }

      // 时间显示更新函数
      function updateTimeDisplay() {
            const currentTime = audio.currentTime;
            const duration = audio.duration || 0;
            timeDisplay.textContent = `${formatTime(currentTime)} / ${formatTime(duration)}`;
      }

      // DOM元素获取
      const dom = {
            lyricsCanvas: document.getElementById('lyricsCanvas'),
            
            playBtn: document.getElementById('playBtn'),
            progress: document.getElementById('progress'),
            timeDisplay: document.getElementById('timeDisplay')
            
      };
      const lyricsCtx = dom.lyricsCanvas.getContext('2d');


      
      
      // LRC歌词数据
      const lrcText = `
假如世界没有你
词曲: 马健涛
编曲: 马健涛
混音: 马健涛
母带: 马健涛
出品: 亚伦影音工作室
假如这世界没有了你
我活着有什么意义
假如有一天找不到你
我哭的比谁都委屈
假如你厌倦了别离
我等着你的归期
假如生命中没有了你
我的心情不会美丽
假如这世界没有你
什么都提不起兴趣
假如有一天又见到了你
幸福的会把眼泪滴
假如你爱情不如意
我该不该靠近你
假如你生活不如意
欢迎回到我这里
假如你厌倦了别离
我等着你的归期
假如生命中没有了你
我的心情不会美丽
假如这世界没有你
什么都提不起兴趣
假如有一天又见到了你
幸福的会把眼泪滴
假如你爱情不如意
我该不该靠近你
假如你生活不如意
欢迎回到我这里
假如这世界没有你
什么都提不起兴趣
假如有一天又见到了你
幸福的会把眼泪滴
假如你爱情不如意
我该不该靠近你
假如你生活不如意
欢迎回到我这里
欢迎回到我这里

      `;

      //解析LRC歌词
      function parseLRC() {
            return lrcText.split('\n')
                .filter(line => line.trim() && line.includes('['))
                .map(line => {
                  const timeMatch = line.match(/\[(\d+):(\d+)\.(\d+)\]/);
                  if (!timeMatch) return null;
                  const time = parseInt(timeMatch) * 60 + parseInt(timeMatch) + parseInt(timeMatch)/100;
                  const text = line.replace(/\[.*?\]/g, '').trim();
                  return text ? { time, text } : null;
                })
                .filter(item => item)
                .sort((a, b) => a.time - b.time);
      }
      const lyricsList = parseLRC();
      let currentLyricIndex = -1;
      let floatingLyrics = [];

      class FloatingLyric {
            constructor(text) {
                this.text = text;
               
                this.x = Math.random() * (dom.lyricsCanvas.width - 100);
                this.y = Math.random() * (dom.lyricsCanvas.height - 30);
                this.vx = (Math.random() - 0.5) * 0.5;
                this.vy = (Math.random() - 0.5) * 0.5;
                this.opacity = 0;
                this.targetOpacity = 0.8 + Math.random() * 0.2;
                this.size = 30 + Math.random() * 7;
                this.color = `hsl(${Math.random() * 60}, 100%, 70%)`;
                this.life = 0;
                this.maxLife = 10;
                this.fadeInDuration = 1;
                this.fadeOutDuration = 2;
                this.isActive = true;
               
                lyricsCtx.font = `${this.size}px 微软雅黑`;
                this.textWidth = lyricsCtx.measureText(this.text).width;
            }

            update(deltaTime) {
                this.life += deltaTime;
                this.x += this.vx;
                this.y += this.vy;

               
                if (this.x < 10) {
                  this.x = 10;
                  this.vx *= -0.8;
                } else if (this.x + this.textWidth > dom.lyricsCanvas.width - 10) {
                  this.x = dom.lyricsCanvas.width - this.textWidth - 10;
                  this.vx *= -0.8;
                }
                if (this.y < this.size + 10) {
                  this.y = this.size + 10;
                  this.vy *= -0.8;
                } else if (this.y > dom.lyricsCanvas.height - 10) {
                  this.y = dom.lyricsCanvas.height - 10;
                  this.vy *= -0.8;
                }

               
                if (this.life < this.fadeInDuration) {
                  this.opacity = (this.life / this.fadeInDuration) * this.targetOpacity;
                } else if (this.life > this.maxLife - this.fadeOutDuration) {
                  this.opacity = ((this.maxLife - this.life) / this.fadeOutDuration) * this.targetOpacity;
                } else {
                  this.opacity = this.targetOpacity;
                }
            }

            draw() {
                if (this.opacity <= 0) return;
                lyricsCtx.save();
                lyricsCtx.globalAlpha = this.opacity;
                lyricsCtx.font = `${this.size}px 微软雅黑`;

               
                lyricsCtx.fillStyle = '#000';
                for (let i = 1; i <= 3; i++) {
                  lyricsCtx.fillText(this.text, this.x + i, this.y + i);
                }
               
                lyricsCtx.fillStyle = this.color;
                lyricsCtx.fillText(this.text, this.x, this.y);

            
                lyricsCtx.shadowBlur = 10;
                lyricsCtx.shadowColor = this.color;
                lyricsCtx.shadowOffsetX = 0;
                lyricsCtx.shadowOffsetY = 0;

                lyricsCtx.restore();
            }

            startFadeOut() {
                this.maxLife = this.life + this.fadeOutDuration;
                this.isActive = false;
            }
      }

      // 最后一句歌词特殊处理
      class LastLyric {
            constructor(text) {
                this.text = text;
                this.opacity = 0;
               
this.size = 30;
                this.color = "#fff666";
                this.isActive = false;
                this.fadeInDuration = 2;
                this.fadeOutDuration = 2;
                this.life = 0;

                this.maxLife = 30;
            }

            update(deltaTime) {
                this.life += deltaTime;
                if (!this.isActive) {
                  this.opacity = 0;
                  return;
                }

               
                if (this.life < this.fadeInDuration) {
                  this.opacity = (this.life / this.fadeInDuration);
                } else if (this.life > this.maxLife - this.fadeOutDuration) {
                  this.opacity = ((this.maxLife - this.life) / this.fadeOutDuration);
                  
                  if (this.opacity <= 0) {
                        this.deactivate();
                  }
                } else {
                  this.opacity = 1;
                }
            }

            draw() {
                if (!this.isActive || this.opacity <= 0) return;
                lyricsCtx.save();
                lyricsCtx.globalAlpha = this.opacity;
                lyricsCtx.font = `bold ${this.size}px 微软雅黑`;
                lyricsCtx.textAlign = 'center';
                lyricsCtx.textBaseline = '10';

               
                lyricsCtx.fillStyle = '#000';
                lyricsCtx.fillText(this.text, dom.lyricsCanvas.width / 2 + 2, dom.lyricsCanvas.height / 2 + 2);

               
                lyricsCtx.fillStyle = this.color;
                lyricsCtx.fillText(this.text, dom.lyricsCanvas.width / 2, dom.lyricsCanvas.height / 2);

               
                lyricsCtx.shadowBlur = 15;
                lyricsCtx.shadowColor = this.color;

                lyricsCtx.restore();
            }

            activate() {
                this.isActive = true;
                this.life = 0;
                this.opacity = 0;
            }

            deactivate() {
                this.isActive = false;
                this.opacity = 0;
                this.life = 0;
            }
      }
      const lastLyric = new LastLyric("欢迎回到我这里");
      let isLastLyricActive = false;

      

      //核心动画循环
      let lastTime = 0;
      function animate(timestamp) {
            if (audio.paused) {
                requestAnimationFrame(animate);
                return;
            }

            const deltaTime = (timestamp - lastTime) / 1000;
            lastTime = timestamp;
            lyricsCtx.clearRect(0, 0, dom.lyricsCanvas.width, dom.lyricsCanvas.height);
            

            const currentAudioTime = audio.currentTime;
            let targetLyricIndex = -1;

   
            for (let i = 0; i < lyricsList.length; i++) {
                if (currentAudioTime >= lyricsList.time) {
                  targetLyricIndex = i;
                } else {
                  
                  break;
                }
            }

      
            if (targetLyricIndex !== -1 && targetLyricIndex !== currentLyricIndex) {
               
                if (targetLyricIndex !== lyricsList.length - 1) {
                  lastLyric.deactivate();
                  isLastLyricActive = false;
                }

                const targetLyric = lyricsList;
                if (targetLyricIndex === lyricsList.length - 1) {
               
                  lastLyric.activate();
                  isLastLyricActive = true;
                } else {
                  
                  const newLyric = new FloatingLyric(targetLyric.text);
                  
                  const nextLyricTime = lyricsList?.time || (audio.duration || currentAudioTime + 5);
                  newLyric.maxLife = nextLyricTime - targetLyric.time + 1;
                  floatingLyrics.push(newLyric);
                }

                currentLyricIndex = targetLyricIndex;
            }

            
            floatingLyrics = floatingLyrics.filter(lyric => {
                lyric.update(deltaTime);
                lyric.draw();
               
                return lyric.life < lyric.maxLife && lyric.opacity > 0.01;
            });

            lastLyric.update(deltaTime);
            lastLyric.draw();

         
            if (audio.duration) {
                const progressPercent = (audio.currentTime / audio.duration) * 100;
                dom.progress.value = progressPercent;
                updateTimeDisplay();
            }

            requestAnimationFrame(animate);
      }

      // 播放/暂停按钮事件
      dom.playBtn.addEventListener('click', () => {
            if (audio.paused) {
                audio.play().then(() => {
                  
                  
                  dom.playBtn.textContent = '暂停';
                  
                  if (isLastLyricActive) {
                        lastLyric.deactivate();
                        isLastLyricActive = false;
                  }
                  
                  lastTime = performance.now();
                  requestAnimationFrame(animate);
                }).catch(e => console.error('音频播放失败:', e));
            } else {
               
                audio.pause();
               
                dom.playBtn.textContent = '播放';
            }
      });

      // 进度条拖动事件
      dom.progress.addEventListener('input', () => {
            if (!audio.duration) return;
            const targetTime = (dom.progress.value / 100) * audio.duration;
            audio.currentTime = targetTime;
            currentLyricIndex = -1;
            floatingLyrics = [];
         
            lastLyric.deactivate();
            isLastLyricActive = false;
            updateTimeDisplay();

         
            let targetLyricIndex = -1;
            for (let i = 0; i < lyricsList.length; i++) {
                if (targetTime >= lyricsList.time) {
                  targetLyricIndex = i;
                } else {
                  break;
                }
            }

            if (targetLyricIndex !== -1) {
                const targetLyric = lyricsList;
                if (targetLyricIndex === lyricsList.length - 1) {
                  lastLyric.activate();
                  isLastLyricActive = true;
                } else {
                  const newLyric = new FloatingLyric(targetLyric.text);
                  
                  newLyric.life = targetTime - targetLyric.time;
                  
                  const nextLyricTime = lyricsList?.time || (audio.duration || targetTime + 5);
                  newLyric.maxLife = nextLyricTime - targetLyric.time + 1;
                  
                  if (newLyric.life > newLyric.maxLife) {
                        newLyric.startFadeOut();
                  }
                  floatingLyrics.push(newLyric);
                }
            }

            
            dom.playBtn.textContent = audio.paused ? '播放' : '暂停';
      });

      // 音频结束事件
      audio.addEventListener('ended', () => {
            audio.currentTime = 0;
            audio.play();
            dom.playBtn.textContent = '暂停';
            
            currentLyricIndex = -1;
            floatingLyrics = [];
         
            lastLyric.deactivate();
            isLastLyricActive = false;
            lastTime = performance.now();
            requestAnimationFrame(animate);
      });

      // 音频加载完成事件
      audio.addEventListener('loadedmetadata', updateTimeDisplay);

      // 初始化自动播放
      audio.play().then(() => {
         
            dom.playBtn.textContent = '暂停';
            lastTime = performance.now();
            requestAnimationFrame(animate);
      }).catch(() => {
            console.log('自动播放被阻止,请点击播放按钮开始');
            dom.timeDisplay.textContent = '00:00 / --:--';
      });
    </script>

红影 发表于 2025-10-3 21:59

这个词同步很特别,好看。欣赏亚伦老师好帖{:4_199:}

老谟深虑 发表于 2025-10-4 09:58

         欣赏老师的代码音画,点赞!

小辣椒 发表于 2025-10-4 22:06

亚纶这个歌词走动效果可以去微风论坛看看最近新进去的那个了了的代码,感觉他的歌词游动效果漂亮一点

小辣椒 发表于 2025-10-4 22:07

看看是差不多的,反正歌词不要挡住人物

亚伦影音工作室 发表于 2025-10-5 09:36

http://www.llz123.net/llz/llz/mulu/tongnian/playlist.html
页: [1]
查看完整版本: 假如世界没有你