找回密码
 立即注册
搜索
楼主: admin

测试专用

[复制链接]

1028

主题

2657

回帖

9896

积分

管理员

积分
9896
 楼主| 发表于 7 天前 | 显示全部楼层

1028

主题

2657

回帖

9896

积分

管理员

积分
9896
 楼主| 发表于 7 天前 | 显示全部楼层
</strong>
<div class="pti">
<div class="pdbt">
</div>
<div class="authi">
<img class="authicn vm" id="authicon2437637" src="static/image/common/online_guibin.gif" />
<em id="authorposton2437637">发表于 2025-12-9 21:28</em>
<span class="pipe">|</span>
<a href="forum.php?mod=viewthread&amp;tid=88742&amp;page=1&amp;authorid=7534" rel="nofollow">只看该作者</a>
<span class="none"><img src="static/image/common/arw_r.gif" class="vm" alt="回帖奖励" /></span>
<span class="pipe show">|</span><a href="forum.php?mod=viewthread&amp;tid=88742&amp;extra=&amp;ordertype=1"  class="show">倒序浏览</a>
<span class="pipe show">|</span><a href="javascript:;" class="show">阅读模式</a>
</div>
</div>
</div><div class="pct"><style type="text/css">.pcb{margin-right:0}</style><div class="pcb">

<div class="t_fsz">
<table cellspacing="0" cellpadding="0"><tr><td class="t_f" id="postmessage_2437637">

<style>
    #bj {
        position: relative;
        width: 1264px;
        height: 680px;
        margin-left: -300px;
        margin-top: 10px;
        overflow: hidden;
        background: url();
  background-size: cover;
    }

  .lyrics{margin: 0;z-index: 20;
            top: 89%;display: none;
            left: 50%;
    transform: translate(-50%, -50%);
            height: 100px; /* 调整高度,只容纳当前歌词 */
                   text-align: center;
             position: absolute;animation:  flash 1s infinite alternate;
        }
            .lyric-line{
            width: 100%;
            position: relative;
            height: 60px;
            overflow: visible;
     font: 100 50px '华文隶书', sans-serif;
            line-height: 60px;
           text-align: left;
            white-space: nowrap; /* 禁止换行 */
          filter: drop-shadow(#fff 1px 0 0) drop-shadow(#fff 0 1px 0) drop-shadow(#fff -1px 0 0) drop-shadow(#fff 0 -1px 0);
        }

        .lyric-mask {
            position: absolute;
            top: 0;
            left: 0;
            width: 0;
            overflow: hidden;
        color: #ff0000;
            height: 100%;
            white-space: nowrap;
        }

        .lyric-original {
             color: #00aa00;
            white-space: nowrap;

        }   

#wrapper {z-index: 9;
                position: absolute; writing-mode: vertical-lr;white-space: pre; width: 60px;height: 90%;top: 50px; left: 88%;
                padding: 0px;
                font:normal 2.6em 华文隶书;
                filter: drop-shadow(#fff 1px 0 0) drop-shadow(#fff 0 1px 0) drop-shadow(#fff -1px 0 0) drop-shadow(#fff 0 -1px 0);

        }

        .char {
                display: inline-block;
                padding: 2px 2px;
                opacity: 0;
                transform: translate(var(--x), var(--y));
                animation: fadeIn 1.5s var(--delay) forwards, flash 1s infinite alternate;
        }
       
        @keyframes fadeIn {
                to {
                        transform:scale(1);
                        opacity: 1;
                }
        }
        @keyframes flash {
                to { filter: hue-rotate(360deg)brightness(60%); }
        }

    #g1,#g2,#fullscreen{border-radius: 4px;position: relative;
  color:#fff;background:#0000;box-shadow:  0px 0px 0px 1px #fff;
  padding: 4px 8px;
font-size: 12px;
border: none;
  cursor: pointer;margin: 8px 5px;left: 6%;
}
#player {position:absolute;top: 60%;z-index: 99;
            left: 7%;
width: 300px;
height: 300px;
display: grid;
        place-items: center;
animation: rot 8s linear infinite ;

}
@keyframes rot {to { transform: rotate(360deg);filter: hue-rotate(360deg); }}
#rect {position: absolute;
        width: 30%;
        height: 30%;
display: grid;
        place-items: center;
clip-path: polygon(60% 0, 100% 0, 50% 50%, 40% 100%, 0 100%, 50% 50%);

}
#rect:nth-of-type(1) { background:#5500ff;transform: rotate(0deg);
}
#rect:nth-of-type(2) { background:#ff0000;transform: rotate(45deg);
}
#rect:nth-of-type(3) { background:#00aa00;transform: rotate(90deg);
}
#rect:nth-of-type(4) { background:#fff000;transform: rotate(135deg);
}

  </style>

<div id="bj">

<div id="wrapper">红蔷薇 - 走不完的路</div>

    <div class="lyrics" >
            <div class="lyric-line">
                    <div class="lyric-mask"></div>
                    <div class="lyric-original"></div>
                </div>
            </div>
<div>
<button id="g1"title="竖排歌词">竖排歌词</button>
<button id="g2"title="横排歌词">横排歌词</button>
<span id="fullscreen" title="屏展模式">全屏欣赏</span>
  </div>
<div id="player">
<span  id="rect"></span>
<span  id="rect"></span>
<span  id="rect"></span>
<span  id="rect"></span>
</div>
</div>
<audio id="aud" src="https://s2.ananas.chaoxing.com/sv-w9/audio/96/ad/79/969030f3e99e465e22e7d73f15a2bb19/audio.mp3" loop autoplay></audio>
<script>
    const lrc = `[00:01.00]红蔷薇 - 走不完的路
[00:08.00]出品 亚伦影音工作室
[00:19.98]人生就像趟不完的河
[00:24.23]无论多少曲折都要过
[00:28.59]风一程雨一程艰难跋涉
[00:32.97]所有苦累全都埋心窝
[00:37.42]人生就像唱不完的歌
[00:41.72]酸甜苦辣又能跟谁说
[00:46.10]爱一场痛一场历尽苦涩
[00:50.42]受过的伤今生难愈合
[00:54.83]人的这一生起起落落
[00:59.10]不知要面对多少坎坷
[01:03.58]走不完的路爬不完的坡
[01:07.88]无论多难都不能退缩
[01:12.27]人的这一生对对错错
[01:16.61]谁能参透这世间因果
[01:21.09]流不完的泪受不完寂寞
[01:25.39]总有挥之不去的困惑
[01:47.30]人生就像唱不完的歌
[01:51.51]酸甜苦辣又能跟谁说
[01:55.94]爱一场痛一场历尽苦涩
[02:00.24]受过的伤今生难愈合
[02:04.59]人的这一生起起落落
[02:08.94]不知要面对多少坎坷
[02:13.40]走不完的路爬不完的坡
[02:17.71]无论多难都不能退缩
[02:21.99]人的这一生对对错错
[02:26.40]谁能参透这世间因果
[02:30.81]流不完的泪受不完寂寞
[02:35.17]总有挥之不去的困惑
[02:39.46]人的这一生起起落落
[02:43.82]不知要面对多少坎坷
[02:48.24]走不完的路爬不完的坡
[02:52.57]无论多难都不能退缩
[02:56.96]人的这一生对对错错
[03:01.22]谁能参透这世间因果
[03:05.67]流不完的泪受不完寂寞
[03:10.04]总有挥之不去的困惑
[03:14.38]总有挥之不去的困惑
`;

   const aud= document.getElementById('aud');
        const lyrics = parseLyrics(lrc);
        const lyricMask = document.querySelector('.lyric-mask');
        const lyricOriginal = document.querySelector('.lyric-original');

        let currentIndex = -1;
        let currentLyric = null;

        // 解析歌词(支持两种格式)
        function parseLyrics(lrcText) {
            const lyrics = [];
            if (lrcText.includes('karaoke.add')) {
                const lineRegex = /karaoke\.add\('([^']+)', '([^']+)', '([^']+)', '([^']+)'\);/g;
                let match;
                while ((match = lineRegex.exec(lrcText)) !== null) {
                    const startTime = timeToMs(match[1]);
                    const endTime = timeToMs(match[2]);
                    const text = match[3].replace(/\[|\]/g, '').trim();
                    const durations = match[4].split(',').map(Number);
                    if (text) {
                        lyrics.push({startTime, endTime, text, durations});
                    }
                }
            }
            else if (lrcText.includes('[')) {
                const lines = lrcText.split('\n').filter(line => line.trim());
                lines.forEach((line, index) => {
                    const timeMatch = line.match(/\[(\d+:\d+\.\d+)\]/);
                    if (timeMatch) {
                        const timeStr = timeMatch[1];
                        const text = line.replace(/\[.*?\]/, '').trim();
                        if (text) {
                            const startTime = timeToMs(timeStr);
                            const nextLine = lines[index + 1];
                            const nextTimeMatch = nextLine ? nextLine.match(/\[(\d+:\d+\.\d+)\]/) : null;
                            const endTime = nextTimeMatch ? timeToMs(nextTimeMatch[1]) : startTime + 5000;
                            lyrics.push({
                                startTime,
                                endTime,
                                text,
                                durations: calculateCharDurations(text, startTime, endTime)
                            });
                        }
                    }
                });
            }
            return lyrics;
        }
        function calculateCharDurations(text, startTime, endTime) {
            const totalDuration = endTime - startTime;
            const charCount = text.length;
            const baseDur = Math.floor(totalDuration / charCount);
            const durations = new Array(charCount).fill(baseDur);
            const remainder = totalDuration % charCount;
            for (let i = 0; i < remainder; i++) {
                durations++;
            }
            return durations;
        }
        function timeToMs(timeStr) {
            const parts = timeStr.split(':');
            const minutes = parseInt(parts[0], 10);
            const secondsAndMs = parts[1].split('.');
            const seconds = parseInt(secondsAndMs[0], 10);
            const ms = parseInt(secondsAndMs[1] || 0, 10);
            return minutes * 60 * 1000 + seconds * 1000 + ms;
        }
        function getCurrentLyricIndex(lyrics, currentTimeMs) {
            for (let i = 0; i < lyrics.length; i++) {
                if (currentTimeMs >= lyrics.startTime && currentTimeMs <= lyrics.endTime) {
                    return i;
                }
            }
            return -1;
        }
        function updateLyricDisplay(index) {
            if (index < 0 || index >= lyrics.length) return;
            currentIndex = index;
            currentLyric = lyrics[index];
            lyricOriginal.textContent = currentLyric.text;
            lyricMask.textContent = currentLyric.text;
            lyricMask.style.width = '0%';
        }
        function updateLyricMask(currentTimeMs) {
            if (!currentLyric) return;
            const lyricStartTime = currentLyric.startTime;
            const elapsed = currentTimeMs - lyricStartTime;
            const totalDuration = currentLyric.durations.reduce((sum, d) => sum + d, 0);
            let charIndex = 0;
            let accumulatedTime = 0;

            for (let i = 0; i < currentLyric.durations.length; i++) {
                accumulatedTime += currentLyric.durations;
                if (elapsed <= accumulatedTime) {
                    charIndex = i + 1;
                    break;
                }
            }

            if (elapsed >= totalDuration) {
                charIndex = currentLyric.text.length;
            }

            charIndex = Math.min(charIndex, currentLyric.text.length);

            const tempSpan = document.createElement('span');
            tempSpan.style.visibility = 'hidden';
            tempSpan.style.position = 'absolute';
            tempSpan.style.fontSize = '50px';
            tempSpan.style.fontWeight = '300';
            document.body.appendChild(tempSpan);

            const visibleText = currentLyric.text.substring(0, charIndex);
            tempSpan.textContent = visibleText;
            const width = tempSpan.offsetWidth;
            document.body.removeChild(tempSpan);

            lyricMask.style.width = `${width}px`;
        }

        // 监听更新歌词
        aud.addEventListener('timeupdate', () => {
            const currentTimeMs = aud.currentTime * 1000;
            const index = getCurrentLyricIndex(lyrics, currentTimeMs);

            if (index !== currentIndex) {
                updateLyricDisplay(index);
            }

            updateLyricMask(currentTimeMs);
        });
        updateLyricDisplay(0);



const gcAr = lrc2HC(lrc);
        let curkey = 0, isSeeking = false;

        aud.ontimeupdate = () => {
                if(curkey > gcAr.length - 1) return;
                if(aud.currentTime >= gcAr[curkey][0]) {
                        const gap = gcAr[curkey + 1]?.[0] ?? 0 - gcAr[curkey][0];
                        showLrc(gcAr[curkey][1], wrapper, gap);
                }
        };

        aud.onended = () => {
                curkey = 0;
                aud.play();
        }

        aud.onseeked = () => calcKey();

        function lrc2HC(text) {
                let lrcAr = [];
                let ar = text.trim().split('\n');
                ar.sort();
                let reg = /\[(\d+)[.:](\d+)[.:](\d+)\](.*)/;
                ar.forEach(item => {
                        if(reg.test(item)) {
                                let result = item.match(reg);
                                let tmsg = parseInt(result[1]) * 60 + parseInt(result[2]) + parseInt(result[3]) / 1000;
                                lrcAr.push([tmsg, result[4].trim()]);
                        }
                });
                return lrcAr ? lrcAr : [0, 'HUACHAO'];
        };

        function calcKey() {
                for (let j = 0; j < gcAr.length; j++) {
                        if (aud.currentTime <= gcAr[j][0]) {
                                curkey = j - 1;
                                break;
                        }
                }
                if (curkey < 0) curkey = 0;
                if (curkey > gcAr.length - 1) curkey = gcAr.length - 1;
                let time = gcAr[curkey + 1]?.[0] ?? 0 - gcAr[curkey][0];
                isSeeking = false;
                showLrc(gcAr[curkey][1], wrapper, time);
        }

        function showLrc(str, targetElm, time) {
                if(isSeeking) return;
                targetElm.innerHTML = '';
                const chars = str.split('').map(c => c === ' ' ? ' ' : c);
                const frg = document.createDocumentFragment();
                chars.forEach((char, idx) => {
                        const span = document.createElement('span');
                        span.innerHTML = char;
                        span.classList.add('char');
                        const x = Math.random() * (Math.random() > 0.5 ? 600 : -300);
                        const y = Math.random() * (Math.random() > 0.5 ? 600 : -300);
                        span.style.cssText += `
                                color: #${Math.random().toString(16).substring(2,8)};
                                --x: ${x}px;
                                --y: ${y}px;
                                --delay: ${Math.random() * 0.5}s;
                        `;
                        frg.appendChild(span);
                });
                targetElm.appendChild(frg);
                curkey ++;
                setTimeout(() =>isSeeking = false, time);
        }
</script>


<script>var eleZxxSlides = document.querySelectorAll('zxx-slide');
[].slice.call(eleZxxSlides).forEach(function (container) {
        var timerSlide = null;
        var indexSlide = 0;
        container.addEventListener('mouseover', function () {
                clearTimeout(timerSlide);
        });
        container.addEventListener('mouseout', function () {
                clearTimeout(timerSlide);
                funSlide();
        });
       
        var eleSlides = [].slice.call(container.querySelectorAll('p'));
        var eleButtons = [].slice.call(container.querySelectorAll('button'));
       
       
        eleButtons.forEach(function (button, index) {
                ['mouseover', 'click'].forEach(function (eventType) {
                        button.addEventListener(eventType, function () {
                                clearTimeout(timerSlide);
                                indexSlide = index;
                                funSlide();
                        });
                });
        });

       
        eleSlides.forEach(function (slide, index) {
                slide.addEventListener('animationend', function () {
                        eleSlides.forEach(function (slide2) {
                                if (slide2.classList.contains('in') == false) {
                                        slide2.style.display = '';
                                }
                        });
                });
        });
       
        var funSlide = function() {
                eleSlides.forEach(function (slide, index) {if(!aud.paused){               
                        if (indexSlide == index) {
                                slide.classList.add('in');
                                slide.style.display = 'block';
                        } else if (slide.classList.contains('in')) {
                                slide.classList.remove('in');
                        }
                }});
                eleButtons.forEach(function (button, index) {
                        button.classList.remove('active');
                        if (indexSlide == index) {
                                button.classList.add('active');
                        }
                });
               
                timerSlide = setTimeout(function () {
                        indexSlide++;
                        if (indexSlide == eleSlides.length) {
                                indexSlide = 0;
                        }
                        funSlide();
                }, 6000);
        }
       
        indexSlide++;

        setTimeout(funSlide, 2000);
});

var g1=document.getElementById("wrapper");

const g2 = document.querySelector('.lyrics');
function btn1() {

            g1.style.display = 'block';
            g2.style.display = 'none';
        }

        function btn2() {
           g1.style.display = 'none';
            g2.style.display = 'block';
        }
let fs = true;
        fullscreen.onclick = () => {
            if (fs) {
                fullscreen.innerText = '退出全屏';
                bj.requestFullscreen();
            } else {
                fullscreen.innerText = '全屏欣赏';
                document.exitFullscreen();
            }
            fs = !fs;
        };
player.onclick = () => aud.paused ? (aud.play(),player.style.animationPlayState = 'running',background.style.animationPlayState = 'running') :( aud.pause(),player.style.animationPlayState = 'paused',background.style.animationPlayState = 'paused');
</script></td></tr></table>

1028

主题

2657

回帖

9896

积分

管理员

积分
9896
 楼主| 发表于 7 天前 | 显示全部楼层
视频在上层


<style>
    @import 'https://638183.freep.cn/638183/web/tz/tz.v3.css';
    .pa {
        --offsetX: 81px;
        --bg: beige url('https://cccimg.com/view.php/732b91b3b2043c7eefa3e8bfa095f8c7.jpg') no-repeat center/cover;
        position: relative; /* 父容器相对定位,让子元素绝对定位生效 */
    }
    /* 视频层样式:在静态图上方,半透明不遮挡交互 */
    .pd-vid {
        opacity: 0.6; /* 0-1之间,数值越小越透明(根据需求调整) */
        z-index: 10; /* 视频层层级:高于静态背景(默认z-index:0) */
        position: absolute; /* 绝对定位,覆盖在背景上 */
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover; /* 视频自适应容器,保持比例不拉伸 */
        pointer-events: none; /* 关键!让视频层不拦截点击事件,穿透到下方按钮 */
    }
    /* 交互元素层级提升:确保按钮、进度条在最上层 */
    .tz-lrc, .tz-audio, .tz-bgprog, .tz-fs, .ma {
        z-index: 20 !important; /* 高于视频层(z-index:10) */
        position: relative; /* 让z-index生效 */
    }
</style>

<div id="pa" class="pa"></div>

<script type="module">
    import TZ from 'https://638183.freep.cn/638183/web/tz/tz.v3.js';
    var tz = TZ.TZ('pa');

    var lrcAr = [
        [9.52, "飘雪的季节,", 1.88],
        [11.68, "你轻轻走来,", 1.68],
        [14.24, "静静落满我心怀,", 3.4],
        [18.64, "银装素裹是你迷人姿态。", 4.16],
        [23.44, "你的纯净让我心潮澎湃,", 4.04],
        [28.08, "你是雪花飘落我的窗外,", 3.84],
        [32.8, "你是精灵舞动洁白。", 3.6],
        [37.44, "你是童话,", 1.48],
        [39.2, "你是我梦的期待,", 2.8],
        [42.16, "你让这世界变得更加精彩。", 4.12],
        [46.88, "我心中的小雪,", 2.68],
        [49.76, "你别离开,", 1.8],
        [51.84, "多想感受你那梦幻的色彩,", 4.04],
        [56.32, "多想与你相伴在这洁白世界聆听你那轻柔的天籁,", 9.12],
        [65.68, "我心中的。", 1.36],
        [67.28, "小雪你别离开,", 3],
        [70.56, "多想陪你看那雪花飘下来,", 3.96],
        [75.04, "有你的世界才是最浪漫的存在,", 5.36],
        [80.56, "你是我永远的爱。", 3.56],
        [103.36, "你是雪花飘落我的窗外,", 3.84],
        [108, "你是精灵舞动洁白。", 3.68],
        [112.72, "你是童话,", 1.56],
        [114.56, "你是我梦的期待,", 2.72],
        [117.52, "你让这世界变得更加精彩,", 4.08],
        [122.16, "我心中的小雪,", 2.52],
        [125.12, "你别离开,", 1.76],
        [127.2, "多想感受你那梦幻的色彩,", 3.96],
        [131.6, "多想与你相伴,", 2.72],
        [134.56, "在这洁白世界聆听你那轻柔的天籁,", 6.2],
        [141.04, "我心中的心。", 1.36],
        [143.92, "你别离开,", 1.8],
        [146, "多想陪你看那雪花飘下来,", 3.88],
        [150.4, "有你的世界才是最浪漫的存在,", 5.36],
        [156, "你是我永远的爱。", 3.6]
    ];
    tz.lrc(lrcAr).style('top: 30px');
    tz.add('audio', '', '', {src: 'https://cccimg.com/view.php/d849e51bac812f8582e7999fefb18c71.mp3'});
    // 视频添加时无需额外修改,样式通过CSS类控制
    tz.add('video', '', 'pd-vid', {
        src: 'https://cccimg.com/view.php/8d0bdb3a49c3f61c69dd632996d7131e.mp4',
        autoplay: true, // 自动播放(可选,根据需求添加)
        loop: true, // 循环播放(烘托主题常用)
        muted: true // 静音(避免音频冲突,可选)
    });
    tz.add('img', '', 'ma', {src: 'https://cccimg.com/view.php/3900cf91838bf25d715948bfa68c04f5.png'}).playmp3().style('bottom: 50px');
    tz.bgprog().style('bottom: 20px; color: red');
    tz.fs().style('right: 20px; bottom: 20px');
</script>

1028

主题

2657

回帖

9896

积分

管理员

积分
9896
 楼主| 发表于 6 天前 | 显示全部楼层
{:5_200:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

协同嘉业科技有限公司 ( 京ICP备2024053108号-1 )

GMT+8, 2025-12-16 11:18 , Processed in 0.095626 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表