杨帆 发表于 2026-6-23 19:17

相 遇

本帖最后由 杨帆 于 2026-6-24 23:46 编辑 <br /><br /><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="referrer" content="never" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>相 遇</title>
<style>
@import url("https://fonts.googleapis.com/css2?family=Liu+Jian+Mao+Cao&family=Long+Cang&family=Ma+Shan+Zheng&family=ZCOOL+KuaiLe&family=ZCOOL+QingKe+HuangYou&display=swap");
:root { --color-1: #fff887; --color-2: #fc89e5; --color-3: #fd27d2; --color-4: #9cf9fc; --color-5: #0dd7de; --color-6: #fbcb6d; --color-7: #fb8739; --color-8: #fa5f57;}
.papa {position: relative; display: grid; place-items: center; margin: 30px 0; width: 1280px; height: 750px; left: calc(50% - 81px); transform: translateX(-50%); box-shadow: 3px 3px 6px gray; overflow: hidden; z-index: 1; background: #000 url('') no-repeat center/cover; font-family: "ZCOOL KuaiLe","Ma Shan Zheng","Long Cang","华文行楷","SimHei","Arial","sans-serif";--state:running;}
#mySVG {width:500px;height:500px;z-index:2;top:16%;left:22%;position: absolute;animation:scale 12s ease infinite alternate var(--state); filter: drop-shadow(var(--shadow-offset) 0 0 rgba(255,20,147,.75)); --shadow-offset: clamp(400px, 35vh, 700px); }
.vid { position:absolute;z-index:0;left:-10%;top:-10%;width:120%;height:120%;object-fit:cover;pointer-events:none;object-position:center;}
#fullscreen{position:absolute;bottom:30px;right:30px;font:normal 1.5em 楷体;color:#fff;text-shadow:0 0 3px #000;cursor: pointer;pointer-events: auto;opacity: 0;z-index:15;}
#fullscreen:hover{font-style:italic;}
#lyricDisplay{ height: 100%; letter-spacing: 0px; display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; padding: 0 1em; width: 100%;}
.lyrichar { display: inline-block; opacity: 0; animation: charAppear 0.5s forwards,hue-rotate 1.5s linear infinite; margin: 0 2px;}
#lyric { position:absolute; left: 50%; bottom: 15px; transform: translateX(-50%); z-index: 10; display: flex; flex-direction: column; justify-content: center; height: 160px; width: 90%; text-align: center; filter:drop-shadow(#000 1px 0 0) drop-shadow(#000 0 1px 0) drop-shadow(#000 -1px 0 0) drop-shadow(#000 0 -1px 0); font: 3.5rem "Long Cang","ZCOOL KuaiLe","Ma Shan Zheng","华文行楷","SimHei", "Arial", sans-serif;}
.dop.lyrichar{animation-play-state: paused;}
#but:active:not(:disabled) {transform: translateY(2px);box-shadow: 0 1px 0 rgba(0,0,0,0.15);}
#but:hover{ transform: scale(1.1);transition: transform 0.12s ease;background:#F8F3EB !important;color:#007bff !important;font-weight: bold !important; }
#statusDisplay{position:absolute;z-index:3;font-size:1.5em;font-weight:50;left:25%;top:13%;color:#fff;}
@keyframes charAppear {to {opacity: 1;transform: translate(0%);}} @keyframes hue-rotate {50%{ filter: hue-rotate(360deg); }}
@keyframes scale{0%{transform:translateX(-50%) perspective(800px) rotateY(0deg) scale(0.01);}20%{transform:translateX(-50%) perspective(800px) rotateY(0deg) scale(1);}40%{transform:translateX(-50%) perspective(800px) rotateY(-25deg) scale(1.2);}60%{transform:translateX(-50%) perspective(800px) rotateY(25deg) scale(1.2);}80%{transform:translateX(-50%) perspective(800px) rotateY(0deg) scale(1);}100%{transform:translateX(-50%) perspective(800px) rotateY(0deg) scale(0.01);}}
</style>
</head>
<body>
<div id="papa" class="papa">
<span id="fullscreen">全屏欣赏</span>
<button id="but" onclick="togglePlayPause()" style="position: absolute;min-width:120px;left:2%;top:2%;padding:10px 20px; font-size:16px; cursor:pointer; background:#007bff; color:#F8F3EB; border:none; z-index:12;border-radius:6px;title="&#x2728;暂停&#x2728;"></button>
<div id="lyric">
    <div id="lyricDisplay"></div>
</div>
<audio id="aud" controls style="display: none;" ></audio>
<div id="statusDisplay">播放中: -2:20</div>
<video class="vid" src="https://media-volc.jianpian.info/2769333/article/20260605/c7a1cbaf41fa4fbdb6431bc3ce973190.mp4" autoplay loop playsinline muted></video>
<svg id='mySVG' viewBox="-50 -50 330 330" xmlns="http://www.w3.org/2000/svg">
<defs>
    <linearGradient id="gradColor">
      <stop offset="0" stop-color="red" />
      <stop offset="0.5" stop-color="green" />
      <stop offset="1" stop-color="violet" />
    </linearGradient>   
    <pattern id="texPattern" width="15" height="15" patternUnits="userSpaceOnUse">
      <image
      href="https://638183.freep.cn/638183/small/hxxb.webp"
      width="15"
      height="15"
      crossorigin="anonymous"
      preserveAspectRatio="xMidYMid slice" >         
      <animate attributeName="x" from="0" to="-15" dur="2s" repeatCount="indefinite" />
      </image>   
    </pattern>            
    <symbol id="pb" >            
      <g stroke=url(#gradColor)
    stroke-width= 1.5
    stroke-linecap= round
    stroke-linejoin= round
    stroke-dasharray=2 4
    stroke-dashoffset=0
    opacity=1 ><path id="svg_3" fill="url(#texPattern)" d="m38.31086,191.09489c5.78428,-5.03518 10.69327,-11.03234 12.76673,-17.84143c-6.20066,3.92981 -11.88759,10.25068 -20.53719,10.01122c-6.52991,0.31242 -14.30852,0.31771 -18.90504,-4.23498c-10.27193,-6.88575 -13.03126,-20.64812 -4.5964,-29.41119c5.77215,-6.32728 15.85158,-9.01022 25.10159,-8.0612c5.82823,-2.06152 -1.13994,-7.28147 -1.8407,-10.53927c-4.33776,-11.81727 5.88126,-25.99187 20.90752,-27.35319c10.77769,-1.28985 21.31377,4.52632 26.58745,12.07447c2.86588,5.28158 1.37265,11.2758 0.70402,16.75508c-2.2516,2.75354 -8.01824,9.41507 0.21095,8.89036c8.1363,-0.10734 16.72834,1.88388 22.09349,7.27751c7.8475,7.26412 8.56734,19.26815 0.67194,26.69074c-4.17642,4.52106 -10.44352,8.13952 -17.53675,7.93807c-6.94261,0.58426 -14.46042,-0.6713 -19.38352,-5.0811c-2.09971,-1.22653 -7.2447,-5.86063 -7.24293,-4.84436c5.14256,8.93102 10.95766,18.20578 21.24511,23.74008c3.67562,2.46371 -5.59854,0.76988 -7.84365,1.27202c-13.60279,0.01002 -27.20552,0.02024 -40.80831,0.03031c2.80187,-2.43774 5.60392,-4.87538 8.40568,-7.31313z">               
<animate attributeName="stroke-dashoffset" from="0" to="-180" begin="0s" dur="8s" repeatCount="indefinite" />      
      </path>
      </g>      
   </symbol>
</defs>   
<use href="#pb" x="0" y="0"></use>
<use href="#pb" x="115" y="-105"></use>
<use href="#pb" x="115" y="0"></use>
<use href="#pb" x="0" y="-105"></use>
</svg>
</div>
<script>
(function(){
    const audioPlayer = document.getElementById('aud');
    const lyricDisplay = document.getElementById('lyricDisplay');
    let currentLyricIndex = -1;
    let isUpdating = false;
    let lyrics = [];
    const lrcText = `
相遇
(男唱:)
多年前 与你不期而遇
追梦的季节
从此开满鲜花也飘洒雨滴
多年后 仍难忘记
彷徨的少年 期盼重逢
又怕等待与别离
等待与别离
啊 大幕起落
你在光影间 吟唱浪漫传奇
曲终人散
有一份温暖 始终珍藏心底
(女唱:)
多年前 与你惊鸿一遇
逐梦的年华
从此缀满星光 也洒落诗意
多年后 仍常念起
青涩的模样 渴望相见
又惧岁月与疏离
岁月与疏离
男:
啊,时光流转
你在回忆里添一段
温柔序曲
女:
聚散有时
有一缕牵挂 始终萦绕心底

`;
function parseLrc(lrc) {
    const lyrics = [];
    const lines = lrc.trim().split('\n');
    const lrcRegex = /\[(\d{2}):(\d{2})\.(\d{2})\](.*)/;
    lines.forEach(line => {
      const match = line.match(lrcRegex);
      if (match) {
            const minutes = parseInt(match);
            const seconds = parseInt(match);
            const ms = parseInt(match);
            const totalSeconds = minutes * 60 + seconds + ms / 100;
            const text = match.trim();
            lyrics.push({time: totalSeconds, text: text});
      }
    });
    return lyrics;
}

function displayLyricCharByChar(text) {
    lyricDisplay.innerHTML = '';
    const chars = text.split('');
    const colorList = ['var(--color-1)', 'var(--color-2)', 'var(--color-3)',
                     'var(--color-4)', 'var(--color-5)', 'var(--color-6)'];
    chars.forEach((char, i) => {
      const span = document.createElement('span');
      span.className = 'lyrichar';
      span.style.color = colorList;
      if (char === ' ') {
            span.innerHTML = '&nbsp;';
      } else {
            span.textContent = char;
      }
      const offset = i === 0 ? 0 : i * 30;
      span.style.transform = `translateY(${offset}px)`;
      span.style.animationDelay = `${i * 0.08}s`;
      if (/[,。!?,.!?]/.test(char)) {
            span.style.animationDelay = `${i * 0.08 + 0.08}s`;
      }
      lyricDisplay.appendChild(span);
    });
}

function resetLyrics() {
    currentLyricIndex = -1;
    lyricDisplay.innerHTML = '';
    const allLyricChars = document.querySelectorAll('.lyrichar');
    allLyricChars.forEach(charSpan => charSpan.classList.add('dop'));
}

lyrics = parseLrc(lrcText);
audioPlayer.src = "https://i.uik.cc/view.php/1ef46f72388040d604ef61ac8b305cfb.mp3";

audioPlayer.addEventListener('loadedmetadata', () => {
    if (audioPlayer.duration) {
      const initRemain = audioPlayer.duration;
      statusDisplay.innerHTML = `<span style="color:#CC00FF">播放中:</span><span style="color:#FF0088">${formatTime(-initRemain)}</span>`;
    }
});
audioPlayer.addEventListener('timeupdate', () => {
    if (isUpdating) return;
    isUpdating = true;
   
    setTimeout(()=>isUpdating=false,100);
      const currentTime = audioPlayer.currentTime;
      if(!audioPlayer.paused && audioPlayer.duration) renderPlayTime();
    for (let i = 0; i < lyrics.length; i++) {
      const currentLyricTime = lyrics.time;
      const nextLyricTime = i < lyrics.length - 1 ? lyrics.time : Infinity;
      if (currentTime >= currentLyricTime - 0.3 && currentTime < nextLyricTime + 0.3) {
            if (currentLyricIndex !== i) {
                currentLyricIndex = i;
                displayLyricCharByChar(lyrics.text);
            }
            break;
      }
    }
});

audioPlayer.addEventListener('ended', () => {
    resetLyrics();
    audioPlayer.currentTime = 0;
    isPaused = false;   
    audioPlayer.play().catch(err => console.log("自动重播播放失败", err));      
});

})();

const wave = document.getElementById('mySVG');
const papa = document.getElementById('papa');
const but = document.getElementById('but');
const vids = document.querySelectorAll('video');
const audioPlayer = document.getElementById('aud');
const statusDisplay = document.getElementById('statusDisplay');

let isPaused = true;

function togglePlayPause() {
const allLyricChars = document.querySelectorAll('.lyrichar');
but.innerText = isPaused ? "\u2728暂停\u2728" : "\u2728开启\u2728";
papa.style.setProperty('--state', isPaused ? 'running' : 'paused');
vids.forEach(vid => isPaused ? vid.play() : vid.pause() );

if (isPaused) {
    isPaused = false;
    audioPlayer.play().catch(e=>console.log('播放异常',e));
    wave.unpauseAnimations();   
    allLyricChars.forEach(charSpan => charSpan.classList.remove('dop'));
    statusDisplay.innerHTML = `<span style="color:#CC00FF">播放中:</span><span style="color:#FF0088">${formatTime(-(audioPlayer.duration-audioPlayer.currentTime))}</span>`;
} else {
    isPaused = true;
    audioPlayer.pause();
    wave.pauseAnimations();   
    allLyricChars.forEach(charSpan => charSpan.classList.add('dop'));
    statusDisplay.textContent = '已暂停';
}
}

function formatTime(seconds) {
const abs = Math.abs(seconds);
const m = Math.floor(abs/60);
const s = Math.floor(abs%60);
return `${seconds<0?'-':''}${m}:${s<10?'0':''}${s}`;
}

function renderPlayTime() {
      if(!audioPlayer.duration) return;
      const rem = audioPlayer.duration - audioPlayer.currentTime;
      statusDisplay.innerHTML = `<span style="color:#CC00FF">播放中:</span><span style="color:#FF0088">${formatTime(-rem)}</span>`;
}

let fs = true,fsTimer,butTimer;
fullscreen.onclick = ()=>{
if(fs){
    fullscreen.innerText = '退出全屏';
    papa.requestFullscreen();
}else{
    fullscreen.innerText = '全屏欣赏';
    document.exitFullscreen();
}
fs = !fs;
};
papa.addEventListener('mousemove', () => {
clearTimeout(fsTimer);
clearTimeout(butTimer);
fullscreen.style.opacity = '1';
   but.style.opacity = '1';
fsTimer = setTimeout(() => fullscreen.style.opacity = '0', 2500);
   butTimer = setTimeout(() => but.style.opacity = '0', 2500);
});

document.addEventListener('visibilitychange', () => {
if (document.hidden) {
    if (!audioPlayer.paused) audioPlayer.pause();
} else {
    if (audioPlayer.paused && !audioPlayer.ended) audioPlayer.play().catch(()=>{});
}
});

['contextmenu', 'dragstart', 'selectstart'].forEach(ev =>
papa.addEventListener(ev, (e) => { e.preventDefault(); })
);
window.addEventListener('load', ()=>{
setTimeout(function(){togglePlayPause()},500);
})
</script>
</body>
</html>

杨帆 发表于 2026-6-23 19:17

代码来自年轻老师分享作品,素材来自申木老师分享作品,在此一并表示感谢~

梦江南 发表于 2026-6-23 20:15

外国美女真漂亮,这首歌是网红最爆的歌曲,很喜欢。谢谢杨帆精彩分享!晚上好!{:4_187:}

杨帆 发表于 2026-6-23 20:19

梦江南 发表于 2026-6-23 20:15
外国美女真漂亮,这首歌是网红最爆的歌曲,很喜欢。谢谢杨帆精彩分享!晚上好!

谢谢江南喜欢与鼓励,歌词与旋律也很美,分享一下{:4_190:}

霜染枫丹 发表于 2026-6-23 21:00

我很喜欢这首歌,感谢扬帆的分享,晚上好~~{:4_204:}{:4_190:}

杨帆 发表于 2026-6-23 22:21

霜染枫丹 发表于 2026-6-23 21:00
我很喜欢这首歌,感谢扬帆的分享,晚上好~~

问好枫丹老师,这是很有韵味的一首歌{:4_187:}

红影 发表于 2026-6-23 22:39

歌曲好听,视频里的外国美女很美。
欣赏杨帆好帖{:4_199:}

杨帆 发表于 2026-6-23 22:42

红影 发表于 2026-6-23 22:39
歌曲好听,视频里的外国美女很美。
欣赏杨帆好帖

谢谢影子鼓励,祝欣赏愉快{:4_187:}

雨季工作室 发表于 2026-6-24 16:54

欣赏杨帆老师佳作!

红影 发表于 2026-6-24 17:25

杨帆 发表于 2026-6-23 22:42
谢谢影子鼓励,祝欣赏愉快

视频那么漂亮,前面的那些放大缩小的装饰图不好,破坏了视频的美呢{:4_204:}

杨帆 发表于 2026-6-24 22:16

雨季工作室 发表于 2026-6-24 16:54
欣赏杨帆老师佳作!

谢谢雨季鼓励,祝夏安{:4_190:}

杨帆 发表于 2026-6-24 22:19

红影 发表于 2026-6-24 17:25
视频那么漂亮,前面的那些放大缩小的装饰图不好,破坏了视频的美呢

有道理,祝影子夏安{:4_187:}

红影 发表于 2026-6-25 20:50

杨帆 发表于 2026-6-24 22:19
有道理,祝影子夏安

谢谢杨帆,也祝你夏安{:4_187:}
页: [1]
查看完整版本: 相 遇