马黑黑 发表于 2024-6-4 11:55

宋婷婷·知音

<style>
        #mydiv { margin: 30px 0 30px calc(50% - 721px); width: 1280px; height:720px; background: url('https://638183.freep.cn/638183/t24/2/viyb.jpg') no-repeat 0/cover; border: thick groove lightpink; overflow: hidden; transition: 1s; z-index: 1; user-select: none; position: relative; }
        #mydiv:hover { background-size: 120%; background-position: center; }
        .txtbox { position: absolute; display: grid; place-items: center; left: var(--x1); top: 20px; width: 50px; height: 50px; font: normal 30px sans-serif; text-align: center; color: white; box-sizing: border-box; cursor: pointer; }
        .txtbox::after { position: absolute; content: ''; inset: -2px; border: 2px dashed gray; border-color: green lightgreen yellow orange; border-radius: 50%; box-shadow: inset 0 0 20px plum; transition: 1s; animation: rot 8s linear var(--delay) infinite var(--state); }
        .txtbox:hover::after { box-shadow: inset 0 0 30px green, 0 0 60px white; }
        #vid { position: absolute; bottom: 0; width: 100%; height: calc(100% + 60px); object-fit: cover; mix-blend-mode: screen; pointer-events: none; }
        @keyframes move1 { to { left: var(--x2); } }
        @keyframes move2 { to { left: var(--x1); } }
        @keyframes rot { to { transform: rotate(var(--deg)); } }
</style>

<div id="mydiv">
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=406737036" autoplay></audio>
        <video id="vid" src="https://img.tukuppt.com/video_show/2269348/00/14/66/5e5a2c53955d7.mp4" loop muted></video>
</div>

<script>
(function() {
        const ar = '高山流水覓知音'.split('');
        const ww = 1280, duTime = 16, deTime = 0.5;
        const total = duTime + ar.length * deTime + deTime;
        let sAr = [], step = 0;//, aniName = 'move1';

        ar.forEach((t,k) => {
                let span = document.createElement('span');
                span.className = 'txtbox';
                span.textContent = t;
                span.style.cssText += `
                        --x1: ${ww + k * 60 - ar.length * 60 - 20}px;
                        --x2: ${k * 60 + 10}px;
                        --deg: -1turn;
                        --delay: -${Math.random() * k}s;
                `;
                sAr.push(span);
                mydiv.appendChild(span);
        });

        let playAni = () => {
                let aniName = ['move1','move2'];
                let deg = ['-1turn','1turn'];
                sAr.forEach((item,key) => {
                        item.style.left = ['var(--x1)','var(--x2)'];
                        item.style.setProperty('--deg', deg);
                        let delay = step % 2 > 0 ? deTime * (sAr.length - key - 1) : deTime * key;
                        item.style.animation = `${aniName} ${duTime}s ${delay}s linear forwards var(--state)`;
                });
                step ++;
        };

        let mState = () => {
                mydiv.style.setProperty('--state', ['running','paused'][+aud.paused]);
                sAr.forEach(item => item.title = ['暂停','播放'][+aud.paused]);
                aud.paused ? vid.pause() : vid.play();
        };

        aud.loop = false;
        aud.onplaying = aud.onpause = () => mState();
        aud.onended = () => { step = 0; aud.play(); }
        aud.ontimeupdate = () => { if(aud.currentTime >= total * step) playAni(); };

        sAr.forEach(item => item.onclick = () =>aud.paused ? aud.play(): aud.pause());
})();
</script>

马黑黑 发表于 2024-6-4 11:56

<style>
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); box-shadow: 2px 2px 4px gray; border: thick groove lightblue; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }
</style>
<h2>代码</h2>
<div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">style</span>&gt;</cl-cd>
<cl-cd data-idx="2">&nbsp; &nbsp; #mydiv { <span class="tBlue">margin:</span> 30px 0 30px calc(50% - 721px); <span class="tBlue">width:</span> 1280px; <span class="tBlue">height:</span>720px; <span class="tBlue">background:</span> url(<span class="tMagenta">'https://638183.freep.cn/638183/t24/2/viyb.jpg'</span>) no-repeat 0/cover; <span class="tBlue">border:</span> thick groove lightpink; <span class="tBlue">overflow:</span> hidden; <span class="tBlue">transition:</span> 1s; <span class="tBlue">z-index:</span> 1; <span class="tBlue">user-select:</span> none; <span class="tBlue">position:</span> relative; }</cl-cd>
<cl-cd data-idx="3">&nbsp; &nbsp; #<span class="tBlue">mydiv:</span>hover { <span class="tBlue">background-size:</span> 120%; <span class="tBlue">background-position:</span> center; }</cl-cd>
<cl-cd data-idx="4">&nbsp; &nbsp; .txtbox { <span class="tBlue">position:</span> absolute; <span class="tBlue">display:</span> grid; <span class="tBlue">place-items:</span> center; <span class="tBlue">left:</span> <span class="tBlue">var</span>(--x1); <span class="tBlue">top:</span> 20px; <span class="tBlue">width:</span> 50px; <span class="tBlue">height:</span> 50px; <span class="tBlue">font:</span> normal 30px sans-serif; <span class="tBlue">text-align:</span> center; <span class="tBlue">color:</span> white; <span class="tBlue">box-sizing:</span> border-box; <span class="tBlue">cursor:</span> pointer; }</cl-cd>
<cl-cd data-idx="5">&nbsp; &nbsp; .txtbox::after { <span class="tBlue">position:</span> absolute; <span class="tBlue">content:</span> <span class="tMagenta">''</span>; <span class="tBlue">inset:</span> -2px; <span class="tBlue">border:</span> 2px dashed gray; <span class="tBlue">border-color:</span> green lightgreen yellow orange; <span class="tBlue">border-radius:</span> 50%; <span class="tBlue">box-shadow:</span> inset 0 0 20px plum; <span class="tBlue">transition:</span> 1s; <span class="tBlue">animation:</span> rot 8s linear <span class="tBlue">var</span>(--delay) infinite <span class="tBlue">var</span>(--state); }</cl-cd>
<cl-cd data-idx="6">&nbsp; &nbsp; .<span class="tBlue">txtbox:</span>hover::after { <span class="tBlue">box-shadow:</span> inset 0 0 30px green, 0 0 60px white; }</cl-cd>
<cl-cd data-idx="7">&nbsp; &nbsp; #vid { <span class="tBlue">position:</span> absolute; <span class="tBlue">bottom:</span> 0; <span class="tBlue">width:</span> 100%; <span class="tBlue">height:</span> calc(100% + 60px); <span class="tBlue">object-fit:</span> cover; <span class="tBlue">mix-blend-mode:</span> screen; <span class="tBlue">pointer-events:</span> none; }</cl-cd>
<cl-cd data-idx="8">&nbsp; &nbsp; @keyframes move1 { to { <span class="tBlue">left:</span> <span class="tBlue">var</span>(--x2); } }</cl-cd>
<cl-cd data-idx="9">&nbsp; &nbsp; @keyframes move2 { to { <span class="tBlue">left:</span> <span class="tBlue">var</span>(--x1); } }</cl-cd>
<cl-cd data-idx="10">&nbsp; &nbsp; @keyframes rot { to { <span class="tBlue">transform:</span> rotate(<span class="tBlue">var</span>(--deg)); } }</cl-cd>
<cl-cd data-idx="11">&lt;<span class="tDarkRed">/style</span>&gt;</cl-cd>
<cl-cd data-idx="12">&nbsp;</cl-cd>
<cl-cd data-idx="13">&lt;<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"mydiv"</span>&gt;</cl-cd>
<cl-cd data-idx="14">&nbsp; &nbsp; &lt;<span class="tDarkRed">audio</span> <span class="tRed">id</span>=<span class="tMagenta">"aud"</span> src=<span class="tMagenta">"https://music.163.com/song/media/outer/url?<span class="tRed">id</span>=406737036"</span> autoplay&gt;&lt;<span class="tDarkRed">/audio</span>&gt;</cl-cd>
<cl-cd data-idx="15">&nbsp; &nbsp; &lt;<span class="tDarkRed">video</span> <span class="tRed">id</span>=<span class="tMagenta">"vid"</span> src=<span class="tMagenta">"https://img.tukuppt.com/video_show/2269348/00/14/66/5e5a2c53955d7.mp4"</span> loop muted&gt;&lt;<span class="tDarkRed">/video</span>&gt;</cl-cd>
<cl-cd data-idx="16">&lt;<span class="tDarkRed">/div</span>&gt;</cl-cd>
<cl-cd data-idx="17">&nbsp;</cl-cd>
<cl-cd data-idx="18">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="19">(<span class="tBlue">function</span>() {</cl-cd>
<cl-cd data-idx="20">&nbsp; &nbsp; <span class="tBlue">const</span> ar = <span class="tMagenta">'高山流水覓知音'</span>.split(<span class="tMagenta">''</span>);</cl-cd>
<cl-cd data-idx="21">&nbsp; &nbsp; <span class="tBlue">const</span> ww = 1280, duTime = 16, deTime = 0.5;</cl-cd>
<cl-cd data-idx="22">&nbsp; &nbsp; <span class="tBlue">const</span> total = duTime + ar.length * deTime + deTime;</cl-cd>
<cl-cd data-idx="23">&nbsp; &nbsp; <span class="tBlue">let</span> sAr = [], step = 0;<span class="tGreen">//, aniName = <span class="tMagenta">'move1'</span>;</span></cl-cd>
<cl-cd data-idx="24">&nbsp;</cl-cd>
<cl-cd data-idx="25">&nbsp; &nbsp; ar.forEach((t,k) =&gt; {</cl-cd>
<cl-cd data-idx="26">&nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">let</span> span = <span class="tRed">document</span>.createElement(<span class="tMagenta">'span'</span>);</cl-cd>
<cl-cd data-idx="27">&nbsp; &nbsp; &nbsp; &nbsp; span.className = <span class="tMagenta">'txtbox'</span>;</cl-cd>
<cl-cd data-idx="28">&nbsp; &nbsp; &nbsp; &nbsp; span.textContent = t;</cl-cd>
<cl-cd data-idx="29">&nbsp; &nbsp; &nbsp; &nbsp; span.style.cssText += `</cl-cd>
<cl-cd data-idx="30">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --x1: ${ww + k * 60 - ar.length * 60 - 20}px;</cl-cd>
<cl-cd data-idx="31">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --x2: ${k * 60 + 10}px;</cl-cd>
<cl-cd data-idx="32">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">--deg:</span> -1turn;</cl-cd>
<cl-cd data-idx="33">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">--delay:</span> -${<span class="tRed">Math</span>.random() * k}s;</cl-cd>
<cl-cd data-idx="34">&nbsp; &nbsp; &nbsp; &nbsp; `;</cl-cd>
<cl-cd data-idx="35">&nbsp; &nbsp; &nbsp; &nbsp; sAr.push(span);</cl-cd>
<cl-cd data-idx="36">&nbsp; &nbsp; &nbsp; &nbsp; mydiv.appendChild(span);</cl-cd>
<cl-cd data-idx="37">&nbsp; &nbsp; });</cl-cd>
<cl-cd data-idx="38">&nbsp;</cl-cd>
<cl-cd data-idx="39">&nbsp; &nbsp; <span class="tBlue">let</span> playAni = () =&gt; {</cl-cd>
<cl-cd data-idx="40">&nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">let</span> aniName = [<span class="tMagenta">'move1'</span>,<span class="tMagenta">'move2'</span>];</cl-cd>
<cl-cd data-idx="41">&nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">let</span> deg = [<span class="tMagenta">'-1turn'</span>,<span class="tMagenta">'1turn'</span>];</cl-cd>
<cl-cd data-idx="42">&nbsp; &nbsp; &nbsp; &nbsp; sAr.forEach((item,key) =&gt; {</cl-cd>
<cl-cd data-idx="43">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.style.left = [<span class="tMagenta">'<span class="tBlue">var</span>(--x1)'</span>,<span class="tMagenta">'<span class="tBlue">var</span>(--x2)'</span>];</cl-cd>
<cl-cd data-idx="44">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.style.setProperty(<span class="tMagenta">'--deg'</span>, deg);</cl-cd>
<cl-cd data-idx="45">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="tBlue">let</span> delay = step % 2 &gt; 0 ? deTime * (sAr.length - key - 1) : deTime * key;</cl-cd>
<cl-cd data-idx="46">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item.style.animation = `${aniName} ${duTime}s ${delay}s linear forwards <span class="tBlue">var</span>(--state)`;</cl-cd>
<cl-cd data-idx="47">&nbsp; &nbsp; &nbsp; &nbsp; });</cl-cd>
<cl-cd data-idx="48">&nbsp; &nbsp; &nbsp; &nbsp; step ++;</cl-cd>
<cl-cd data-idx="49">&nbsp; &nbsp; };</cl-cd>
<cl-cd data-idx="50">&nbsp;</cl-cd>
<cl-cd data-idx="51">&nbsp; &nbsp; <span class="tBlue">let</span> mState = () =&gt; {</cl-cd>
<cl-cd data-idx="52">&nbsp; &nbsp; &nbsp; &nbsp; mydiv.style.setProperty(<span class="tMagenta">'--state'</span>, [<span class="tMagenta">'running'</span>,<span class="tMagenta">'paused'</span>][+aud.paused]);</cl-cd>
<cl-cd data-idx="53">&nbsp; &nbsp; &nbsp; &nbsp; sAr.forEach(item =&gt; item.title = [<span class="tMagenta">'暂停'</span>,<span class="tMagenta">'播放'</span>][+aud.paused]);</cl-cd>
<cl-cd data-idx="54">&nbsp; &nbsp; &nbsp; &nbsp; aud.paused ? vid.pause() : vid.play();</cl-cd>
<cl-cd data-idx="55">&nbsp; &nbsp; };</cl-cd>
<cl-cd data-idx="56">&nbsp;</cl-cd>
<cl-cd data-idx="57">&nbsp; &nbsp; aud.loop = false;</cl-cd>
<cl-cd data-idx="58">&nbsp; &nbsp; aud.onplaying = aud.onpause = () =&gt; mState();</cl-cd>
<cl-cd data-idx="59">&nbsp; &nbsp; aud.onended = () =&gt; { step = 0; aud.play(); }</cl-cd>
<cl-cd data-idx="60">&nbsp; &nbsp; aud.ontimeupdate = () =&gt; { <span class="tBlue">if</span>(aud.currentTime &gt;= total * step) playAni(); };</cl-cd>
<cl-cd data-idx="61">&nbsp;</cl-cd>
<cl-cd data-idx="62">&nbsp; &nbsp; sAr.forEach(item =&gt; item.onclick = () =&gt;aud.paused ? aud.play(): aud.pause());</cl-cd>
<cl-cd data-idx="63">})();</cl-cd>
<cl-cd data-idx="64">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
</div>

马黑黑 发表于 2024-6-4 12:05

本帖主要特点:

利用文本生成若干个 span 标签,这些标签可以装饰帖子,同时充当音频的播放控制按钮。

span 标签绝对定位,先排列在帖子的靠右区域,音乐播放时交替运行两套CSS关键帧动画从而左右逐个移动。动画机制算法上似乎不太理想,不过又不是不可以动,将就着用。

span 标签的伪元素 ::after 运行自己的关键帧动画,它可以根据行进方向改变旋转方向。

另,设备指针移入帖子时,:hover 触发的是 background-size 和 background-position 两个属性,前者不响应 transition 时间设定,指针移入移出的动画显得有些突兀,完美的解决方案应该是用伪元素放图、伪元素宽高尺寸变更。

南无月 发表于 2024-6-4 12:42

原来这些字也是小播按纽,功能扩展啦。。
刚才只顾点上去看内光晕和外光晕的变化。。{:4_199:}

南无月 发表于 2024-6-4 12:47

背景触碰可以放大缩小,从右往左移动位置~~
user-select: none;这句没见过,不知道干 啥用的。{:4_173:}

马黑黑 发表于 2024-6-4 12:51

南无月 发表于 2024-6-4 12:47
背景触碰可以放大缩小,从右往左移动位置~~
user-select: none;这句没见过,不知道干 啥用的。

禁止选择

马黑黑 发表于 2024-6-4 12:52

南无月 发表于 2024-6-4 12:42
原来这些字也是小播按纽,功能扩展啦。。
刚才只顾点上去看内光晕和外光晕的变化。。

齿轮形状挺好看的,全网木有

南无月 发表于 2024-6-4 13:02

马黑黑 发表于 2024-6-4 12:05
本帖主要特点:

利用文本生成若干个 span 标签,这些标签可以装饰帖子,同时充当音频的播放控制按钮。



    #mydiv::before { position: absolute; content: ''; inset: 0; transition: 7s; mix-blend-mode: screen; background: url('https://638183.freep.cn/638183/t24/2/viyb.jpg') no-repeat center/cover; }
        #mydiv:hover::before { transform: scale(1.2); }
用伪元素放图、伪元素宽高尺寸变更,缩放大小很漂亮了。
但从右往左移的动画不见了。。
这两个不能同时存在的么。

南无月 发表于 2024-6-4 13:04

#mydiv:hover::before { transform: scale(1.2); }
#mydiv:hover:before { background-position: center; }

#mydiv:hover::before { transform: scale(1.2); background-position: center; }
分开合起来都不行。。{:4_170:}反正试过了~~

梦江南 发表于 2024-6-4 13:18

欣赏老师的又一新作!辛苦了!

马黑黑 发表于 2024-6-4 13:20

梦江南 发表于 2024-6-4 13:18
欣赏老师的又一新作!辛苦了!

{:4_190:}

马黑黑 发表于 2024-6-4 13:21

南无月 发表于 2024-6-4 13:04
#mydiv:hover::before { transform: scale(1.2); }
#mydiv:hover:before { background-position: center;...

css3还是有缺陷的:对 background-* 的绝大多数都不能相应 transition 设定

马黑黑 发表于 2024-6-4 13:21

南无月 发表于 2024-6-4 13:02
#mydiv::before { position: absolute; content: ''; inset: 0; transition: 7s; mix-blend-mode:...

background 图片的位置和样纸应设为 center/cover

醉美水芙蓉 发表于 2024-6-4 16:54

马黑黑 发表于 2024-6-4 17:31

醉美水芙蓉 发表于 2024-6-4 16:54
欣赏老师带来的精彩!

{:4_190:}

南无月 发表于 2024-6-4 17:47

马黑黑 发表于 2024-6-4 12:51
禁止选择

保护措施{:4_173:}

南无月 发表于 2024-6-4 17:48

马黑黑 发表于 2024-6-4 12:52
齿轮形状挺好看的,全网木有

黑氏独创。。独一无二,是真的非常好看。。{:4_199:}。。

南无月 发表于 2024-6-4 17:49

马黑黑 发表于 2024-6-4 13:21
css3还是有缺陷的:对 background-* 的绝大多数都不能相应 transition 设定

好吧,抄个别的代码过来还行。。。
说到更深的就溜了溜了{:4_170:}

南无月 发表于 2024-6-4 17:50

马黑黑 发表于 2024-6-4 13:21
background 图片的位置和样纸应设为 center/cover

这俩常见的样子。。{:4_170:}

马黑黑 发表于 2024-6-4 19:33

南无月 发表于 2024-6-4 17:50
这俩常见的样子。。

position/size

意思是 位置 / 尺寸

center / cover ,就是背景图片居中摆放,以封面(cover)女郎的样纸做尺寸,cover大致意思是保持封面女郎不变形,以最短边为依据,按比例截取最长边
页: [1] 2 3 4 5
查看完整版本: 宋婷婷·知音