守护者
<style>#papa { margin: 20px 0 20px calc(50% - 593px); position: relative; width: 1024px; height: 576px; background: tan url('https://638183.freep.cn/638183/t24/2/guardian.jpg'); box-shadow: 2px 2px 6px #000; user-select: none; z-index: 1; }
.player { position: absolute; cursor: pointer; transition: 1.2s; animation: rot 8s linear infinite var(--state); }
.player:nth-of-type(1) { left: 535px; top: 300px; --deg: 1turn; }
.player:nth-of-type(2) { left: 600px; top: 470px; --deg: -1turn; }
.player:nth-of-type(3) { left: 700px; top: 150px; --deg: 1turn; }
.player:nth-of-type(4) { left: 925px; top: 250px; --deg: -1turn; }
.player:nth-of-type(5) { left: 300px; top: 50px; --deg: 1turn; }
.player:hover { filter: hue-rotate(60deg) drop-shadow(0 0 28px #000); --state: paused; }
@keyframes rot { to { transform: rotate(var(--deg)); } }
</style>
<div id="papa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=29764149" autoplay loop></audio>
<img class="player" src="https://638183.freep.cn/638183/t23/btn/f1.gif" alt="" />
<img class="player" src="https://638183.freep.cn/638183/t23/btn/f2.webp" alt="" />
<img class="player" src="https://638183.freep.cn/638183/t23/btn/f3.png" alt="" />
<img class="player" src="https://638183.freep.cn/638183/t23/btn/f4.png" alt="" />
<img class="player" src="https://638183.freep.cn/638183/t23/btn/f5.png" alt="" />
</div>
<script>
var players = document.querySelectorAll('.player');
var mState = () => {
papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');
players.forEach(player => player.title = aud.paused ? '播放' : '暂停');
};
aud.onplaying = aud.onpause = () => mState();
players.forEach(player => player.onclick = () => aud.paused ? aud.play() : aud.pause());
</script>
本帖主要知识点:
(一)CSS伪类 :nth-of-type(x) 的应用
:nth-of-type(x) 用来设置同一类属的元素第 x 个的样式。本帖,针对 class="player" 的元素对之进行定位、给关键帧动画旋转变量 --deg 赋值,代码在第 4~8 行。
x 将对应在 HTML 代码流中 class="player" 元素出现的顺序。
(二)CSS伪类 :hover 的应用
:hover 伪类用来触发指针设备经过元素之上时的事件,具备双向变化特性(toggle),即,指针移入时从A状态变为B状态,移开后从B状态变回A状态。本帖,:hover 伪类触发两个CSS属性,一是 filter 滤镜,色相变换+阴影投影,二是通过CSS变量 --state 暂停动画。代码在第 9 行。
(三)JS控制多个同类元素
首先需要拿到同类元素的元素对象数组,本帖要操控的元素是 class="player" 的 img 标签,我们只通过类名操作它们:
var players = document.querySelectorAll('.player');
document.querySelectorAll() 是JS ES6内置方法,querySelectorAll('xx') 函数的参数 xx 可以是 #id、.类名、元素名称等等,还可以是复合结构的特定名称,这里用 .player 做参数、指向 class="player" 的所有元素,拿到的是一个元素对象数组。
其次用 for、while 或 forEach 等循环语句操作元素对象数组,本帖使用 forEach 语句,代码在第 26 行和 第 29 行,26行用在联动函数 mState 中,用来动态改变每一个 img 标签的 title 值,29行用于响应图片的点击事件。
以 29 行为例,解释一下它的意思:
players.forEach(player => player.onclick = () => aud.paused ? aud.play() : aud.pause());
语句框架是这样:
players.forEach();
意思是,players 对象的每一个啥啥。啥啥呢?
players.forEach(player);
意思是,每一个 player。players 是前面声明并赋值的元素数组对象,player 则是用来代表 players 数组元素的自定义名称。那么,每一个 player 要干哈呢?
players.forEach( player => player.onclick = () => );
意思是,player 单击事件。单击的预期是啥呢?
players.forEach( player => player.onclick = () => aud.paused ? aud.play() : aud.pause() );
意思是:如果 id="aud" 的 audio 标签暂停,那就让它播放,反之,让它暂停。
一行代码的信息量很大。 <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"><<span class="tDarkRed">style</span>></cl-cd>
<cl-cd data-idx="2"> #papa { <span class="tBlue">margin:</span> 20px 0 20px calc(50% - 593px); <span class="tBlue">position:</span> relative; <span class="tBlue">width:</span> 1024px; <span class="tBlue">height:</span> 576px; <span class="tBlue">background:</span> tan url(<span class="tMagenta">'https://638183.freep.cn/638183/t24/2/guardian.jpg'</span>); <span class="tBlue">box-shadow:</span> 2px 2px 6px #000; <span class="tBlue">user-select:</span> none; <span class="tBlue">z-index:</span> 1; }</cl-cd>
<cl-cd data-idx="3"> .player { <span class="tBlue">position:</span> absolute; <span class="tBlue">cursor:</span> pointer; <span class="tBlue">transition:</span> 1.2s; <span class="tBlue">animation:</span> rot 8s linear infinite <span class="tBlue">var</span>(--state); }</cl-cd>
<cl-cd data-idx="4"> .<span class="tBlue">player:</span>nth-of-type(1) { <span class="tBlue">left:</span> 535px; <span class="tBlue">top:</span> 300px; <span class="tBlue">--deg:</span> 1turn; }</cl-cd>
<cl-cd data-idx="5"> .<span class="tBlue">player:</span>nth-of-type(2) { <span class="tBlue">left:</span> 600px; <span class="tBlue">top:</span> 470px; <span class="tBlue">--deg:</span> -1turn; }</cl-cd>
<cl-cd data-idx="6"> .<span class="tBlue">player:</span>nth-of-type(3) { <span class="tBlue">left:</span> 700px; <span class="tBlue">top:</span> 150px; <span class="tBlue">--deg:</span> 1turn; }</cl-cd>
<cl-cd data-idx="7"> .<span class="tBlue">player:</span>nth-of-type(4) { <span class="tBlue">left:</span> 925px; <span class="tBlue">top:</span> 250px; <span class="tBlue">--deg:</span> -1turn; }</cl-cd>
<cl-cd data-idx="8"> .<span class="tBlue">player:</span>nth-of-type(5) { <span class="tBlue">left:</span> 300px; <span class="tBlue">top:</span> 50px; <span class="tBlue">--deg:</span> 1turn; }</cl-cd>
<cl-cd data-idx="9"> .<span class="tBlue">player:</span>hover { <span class="tBlue">filter:</span> hue-rotate(60deg) drop-shadow(0 0 28px #000); <span class="tBlue">--state:</span> paused; }</cl-cd>
<cl-cd data-idx="10"> @keyframes rot { to { <span class="tBlue">transform:</span> rotate(<span class="tBlue">var</span>(--deg)); } }</cl-cd>
<cl-cd data-idx="11"><<span class="tDarkRed">/style</span>></cl-cd>
<cl-cd data-idx="12"> </cl-cd>
<cl-cd data-idx="13"><<span class="tDarkRed">div</span> <span class="tRed">id</span>=<span class="tMagenta">"papa"</span>></cl-cd>
<cl-cd data-idx="14"> <<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>=29764149"</span> autoplay loop><<span class="tDarkRed">/audio</span>></cl-cd>
<cl-cd data-idx="15"> <<span class="tDarkRed">img</span> class=<span class="tMagenta">"player"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/t23/btn/f1.gif"</span> alt=<span class="tMagenta">""</span> /></cl-cd>
<cl-cd data-idx="16"> <<span class="tDarkRed">img</span> class=<span class="tMagenta">"player"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/t23/btn/f2.webp"</span> alt=<span class="tMagenta">""</span> /></cl-cd>
<cl-cd data-idx="17"> <<span class="tDarkRed">img</span> class=<span class="tMagenta">"player"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/t23/btn/f3.png"</span> alt=<span class="tMagenta">""</span> /></cl-cd>
<cl-cd data-idx="18"> <<span class="tDarkRed">img</span> class=<span class="tMagenta">"player"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/t23/btn/f4.png"</span> alt=<span class="tMagenta">""</span> /></cl-cd>
<cl-cd data-idx="19"> <<span class="tDarkRed">img</span> class=<span class="tMagenta">"player"</span> src=<span class="tMagenta">"https://638183.freep.cn/638183/t23/btn/f5.png"</span> alt=<span class="tMagenta">""</span> /></cl-cd>
<cl-cd data-idx="20"><<span class="tDarkRed">/div</span>></cl-cd>
<cl-cd data-idx="21"> </cl-cd>
<cl-cd data-idx="22"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="23"> <span class="tBlue">var</span> players = <span class="tRed">document</span>.querySelectorAll(<span class="tMagenta">'.player'</span>);</cl-cd>
<cl-cd data-idx="24"> <span class="tBlue">var</span> mState = () => {</cl-cd>
<cl-cd data-idx="25"> papa.style.setProperty(<span class="tMagenta">'--state'</span>, aud.paused ? <span class="tMagenta">'paused'</span> : <span class="tMagenta">'running'</span>);</cl-cd>
<cl-cd data-idx="26"> players.forEach(player => player.title = aud.paused ? <span class="tMagenta">'播放'</span> : <span class="tMagenta">'暂停'</span>);</cl-cd>
<cl-cd data-idx="27"> };</cl-cd>
<cl-cd data-idx="28"> aud.onplaying = aud.onpause = () => mState();</cl-cd>
<cl-cd data-idx="29"> players.forEach(player => player.onclick = () => aud.paused ? aud.play() : aud.pause());</cl-cd>
<cl-cd data-idx="30"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
欣赏学习老师的特效音画“守护者”!{:4_199:} 五朵花都能暂停和播放。{:4_199:} 这个有趣,5个小播分别设置正转反转,每个都能独立操控暂停呢{:4_199:} 小播设置了相同的鼠标触碰的色相和阴影变化,可以很直观地比较不同底色花朵在色相变化60度的情况下的不同展示效果了,这个真好{:4_199:} 美丽的周日,进论坛的人就看到天使的守护,太幸福了把{:4_173:} 红影 发表于 2024-5-26 09:17
美丽的周日,进论坛的人就看到天使的守护,太幸福了把
有空看看8楼 标题很是温暖
背景里的斑驳色调和小花们的鲜艳对比强烈,
天使和花儿之间的守护将生生不息且亘古不变{:4_204:} 本帖最后由 南无月 于 2024-5-26 16:20 编辑
{:4_173:}五个小播联动控制。。小花触碰还有光晕和变色。。
看了说明,看着简单,实际上知识点好多。。{:4_187:}
这贴跟老师站里重点有所不同,加的字没了。{:4_191:} 南无月 发表于 2024-5-26 16:20
这贴跟老师站里重点有所不同,加的字没了。
不一定要加字呀 南无月 发表于 2024-5-26 16:20
这贴跟老师站里重点有所不同,加的字没了。
加字的在这里,好漂酿的:
http://mhh.52qingyin.cn/art/bshow.php?st=3&sd=3&art=mahei_1716682038 这是安琪儿吗?好可爱的天使{:4_181:} 千羽 发表于 2024-5-26 20:12
这是安琪儿吗?好可爱的天使
守护天使 马黑黑 发表于 2024-5-26 20:02
加字的在这里,好漂酿的:
http://mhh.52qingyin.cn/art/bshow.php?st=3&sd=3&art=mahei_1716682038
说的就是这个排字。。
它还带了点立体效果,色彩搭得特别好看 马黑黑 发表于 2024-5-26 09:18
有空看看8楼
看了,也学习了,把它提上去了,更容易先看到{:4_187:} 马黑黑 发表于 2024-5-26 17:57
不一定要加字呀
{:4_170:}
我说呢早上看还有呢。
回了几处都没有。。
得喊才有啊 五个播放器按钮{:4_173:}