马黑黑 发表于 2024-7-28 12:52

红影 发表于 2024-7-28 11:19
ok了,其实还是挺快的@马黑黑

还没有翻页的

马黑黑 发表于 2024-7-28 12:56

<style>
.artbox { position: relative; }
.artbox > p { position: relative; margin: 10px 0; font: normal 18px / 26px sans-serif; }
.artbox mark { color: black; background: lightblue; padding: 2px 4px; }
.textRed { color: red; }
</style>

<div class="artbox">
        <h2 class="textMid">第七讲:加入音、视频及CSS关键帧动画联动控制机制</h2>
        <p>音画帖可以是内容极其丰富的,除了我们前面讲到的图像、音频,还可以有视频、svg、canvas画布等媒体元素。当诸多的可动元素都需要得到与音频的播放和暂停同步控制,我们就有必要将控制机制整合起来,日后做帖子时可以复用,仅需根据帖子的情况对之做少量的增删、修改工作,可以大大提高做帖效率并保证帖子的正常运行。这里,除了音频、关键帧动画外,假设还有一个 id="vid" 的视频需要与音频同步控制,并且,小播在切换播放暂停时能够给出指引性质的提示语,看看该怎么?思路是,我们设计一个自定义函数,它将统一管理所有会动态变化的元素,函数命名为 mState,不需要任何参数,直接对帖子中需要联动控制的东东进行控制:</p>

<div class="hE"><pre>
//JS联动控制函数 mState : 以音频控件的 paused 属性当前值决定动画、视频的播放&暂停,并且提供恰当的
//小播提示语。这里假设:帖子容器 id="papa",小播 id="player",视频 id="vid",音频控件 id="aud"

var mState = () => {
        papa.style.setProperty('--state', aud.paused ? 'paused' : 'running'); //控制css动画播放&暂停
        player.title = aud.paused ? '播放' : '暂停'; //小播提示语
        aud.paused ? vid.pause() : vid.play(); //控制视频播放&暂停
};
</pre></div>

        <p>花括号 <mark>{}</mark> 包裹起来的三行代码就是函数体代码集合,即 mState() 函数要执行的具体内容。各行内容解释如下:</p>
        <p>第5行:这是上一讲的内容,通过JS内置的 <mark>元素.style.setProperty('CSS属性名称','CSS属性值')</mark> 方法改变我们预定义的CSS变量 <span class="textRed">--state</span> 的值来达成控制四叶草旋转与否的目的。我们通过帖子容器元素 papa 来传达 --state 变量值,这样可以控制其下所有使用 --state 变量的子元素(前提是子元素CSS代码不给它赋值,具体说就是 --state: running/paused 不能写在子元素选择器里)。</p>
        <p>第6行:设置小播提示语,<mark>player.title</mark> 可以理解为“小播的标题”,title这里是一个特殊标题,鼠标指针移动到其上时弹出的 tiptop 提示语,它等于(=),问,音乐暂停中么?答,若暂停,那么提示语是“播放”,意思是点我播放,若不是暂停中,那么,提示语是“暂停”,意思是点我暂停。</p>
        <p>第7行,询问音乐是否暂停中,答,若是,视频暂停,反之,视频播放。</p>
        <p>这个 mState() 函数可以根据帖子的情况或自己的设计增删或改变相应内容,实现同一功能比如提示语的确定也可以用不同的方式。不论如何,函数总体功能就是智能地联动控制帖子相应子元素的动作或状态,并通过 audio 音频控件来更智能地操纵这个函数——换言之,通过对音频控件的几个事件的监听来运行 mState() 函数。试看代码:</p>

<div class="hE"><pre>
//监听音频控件的 canplay、playing 和 pause 事件
aud.oncanplay = aud.onplaying = aud.onpause = () => mState();
</pre></div>

        <p>audio 拥有很多的事件,其中, <span class="textRed">canplay</span> 事件指的是音频下载到能够播放的程度,<span class="textRed">playing</span> 事件指音频已经播放中,<span class="textRed">pause</span> 事件指音频暂停中。这三个事件任意一个触发了,都运行 mState() 联动函数,所以把它们放在一块儿写,最后用箭头函数符号 <mark>= () =></mark> 引出要执行的函数 mState(),语句完毕要写上一个小角分号 <mark>;</mark> 以便和其他代码隔开。三个事件被触发的情形大概是这样:打开帖子,audio 音频控件会自动下载 <mark>src="..."</mark> 指向的音乐文件,下载到一定的量就会触发 canplay(可以播放)事件,此时 mState() 函数得到运行,动画、视频可能开始运行,提示语可能按预期做改变。为啥说可能?因为,一切还得看其他的事件监听情况,最近被触发的事件决定当下被管控子元素的状态;playing(已经播放)事件和 canplay 事件几乎同步,但它有更多的触发机会,例如音乐暂停后又播放也都会触发它;pause(暂停)事件可能一开始就得到触发,例如浏览器设置为禁止自动播放音频,若是如此,则 canplay 事件会被中断,音频控件处于暂停状态。pause 事件还会在手动暂停音乐时触发。总之,通过一系列的逻辑设计即监听这三个事件来运行 mState() 函数,可以有效地对帖子的音频视频和动画等进行智能管理,达到同步控制的管控目的。</p>
        <p>如此一来,小播的单击事件就只做一件事情,无需再去管控联动机制的工作:</p>

<div class="hE"><pre>
//小播点击事件 :若音乐暂停中则播放它,反之暂停它
player.onclick = () => aud.paused ? aud.play() : aud.pause();
</pre></div>

        <p>现在,我们可以写一个有视频、有一只飞鹰的帖子,视频和飞鹰都要纳入联动控制函数的管理范畴。以下完整代码,新出现的知识点我会做简单注释,大家注意理解消化。代码可以在线运行:</p>

<div class="hE" id="hE2"><pre>
&lt;!-- 第一部分 :css代码 --&gt;

&lt;style&gt;
/* 帖子容器id选择器 */
#papa {
        position: relative;
        margin: 20px auto;
        width: 800px;
        height: 450px;
        background: url('https://638183.freep.cn/638183/t22/webp/jyiu.webp') no-repeat center/cover;
        overflow: hidden; /* 隐藏溢出 */
}
/* 小播id选择器 */
#player {
        position: absolute;
        right: 40px;
        bottom: 40px;
        width: 120px;
        height: 120px;
        cursor: pointer;
        opacity: .8; /* 透明度设置 :与背景产生美妙融合 */
        animation: rot 8s linear infinite var(--state);
}
/* 飞鹰id选择器 */
#bird {
        position: absolute;
        left: -50px; /* 飞鹰半只身子隐藏 */
        top: 10px;
        animation: fly 6s linear infinite var(--state);
}
/* 视频id选择器 */
#vid {
        position: absolute;
        right: 0;
        bottom: 0;
        width: 200px;
        height: 200px;
        object-fit: cover; /* 视频封面式伸缩 */
        border-radius: 50%; /* 通过边框角半径属性设置形状为圆形 */
        pointer-events: none; /* 禁止视频点击交互 */
        opacity: .5; /* 透明度 :弱化视频以便合适做小播背景 */
        mix-blend-mode: screen; /* 滤镜 :去掉黑底 */
}
/* 关键帧动画一 :小播旋转 */
@keyframes rot { to { transform: rotate(360deg); } }
/* 关键帧动画二 :小鸟飞行 */
@keyframes fly { to { left: 800px; } }
&lt;/style&gt;

&lt;!-- 第二部分 :html代码 父元素带4个子元素 --&gt;

&lt;div id="papa"&gt;
        &lt;audio id="aud" src="https://music.163.com/song/media/outer/url?id=523696075" autoplay loop&gt;&lt;/audio&gt;
        &lt;video id="vid" src="https://img.tukuppt.com/video_show/2421007/00/08/37/5d1ee1f117f9f.mp4" autoplay loop muted&gt;&lt;/video&gt;
        &lt;img id="bird" alt="" src="https://638183.freep.cn/638183/t22/gif/ying1.gif" />
        &lt;img id="player" alt="" src="https://638183.freep.cn/638183/small/4yc.png" title="播放/暂停" /&gt;
&lt;/div&gt;

&lt;!-- 第三部分 :JS代码 --&gt;

&lt;script&gt;

//联动控制函数
var mState = () =&gt; {
        papa.style.setProperty('--state', aud.paused ? 'paused' : 'running'); //控制css动画播放&暂停
        player.title = aud.paused ? '播放' : '暂停'; //小播提示语
        aud.paused ? vid.pause() : vid.play(); //控制视频播放&暂停
};

//audio空间三个监听事件
aud.oncanplay = aud.onplaying = aud.onpause = () =&gt; mState();

//小播点击事件
player.onclick = () =&gt; aud.paused ? aud.play() : aud.pause();

&lt;/script&gt;
</pre></div>

        <p><button id="btnRun2" type="button" value="btn2">点击这里运行代码</button></p>
        <div id="mystage2"></div>
        <p>本节,我们控制的每一个子元素都是通过元素的id达成,这是十分有效的办法。但是想一想:如果我们要控制的子元素数量比较多,是不是得给每一个子元素都分配一个id标识呢?显然这么操作很繁琐、也 不太现实,所以,请思考:有什么好办法智能管控数量众多的子元素的运动与暂停?</p>

        <p><a href="https://www.huachaowang.com/forum.php?mod=viewthread&tid=77307&extra=page%3D1">返回目录</a></p>
       
</div>

<script>
var sc = document.createElement('script');
sc.chartset = 'utf-8';
sc.src = 'https://638183.freep.cn/638183/web/js2024/helight.js';
document.body.appendChild(sc);

var runCodes = (str,ele) => {
        let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
        let js_str, html_str;
        if(str.match(reg) !== null) {
                js_str = str.match(reg);
                html_str = str.replace(js_str, '').trim();
                js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
        } else {
                js_str = '';
                html_str = str.trim();
        }
        ele.innerHTML = html_str;
        let myfunc = new Function(js_str);
        myfunc();
};

var codes = hE2.querySelector('pre').innerText;
btnRun2.onclick = () => {
        runCodes(codes, mystage2);
        btnRun2.disabled = true;
};

</script>

红影 发表于 2024-7-28 17:24

马黑黑 发表于 2024-7-28 12:52
还没有翻页的

我算好的翻页,肯定下一个帖子就是翻页啊{:4_173:}

红影 发表于 2024-7-28 17:30

“设计一个自定义函数,它将统一管理所有会动态变化的元素”
这个好,可以让所有的动态一键管控{:4_187:}

红影 发表于 2024-7-28 17:31

黑黑的讲解很详细,每次学习都有新的收获{:4_204:}

红影 发表于 2024-7-28 17:31

黑黑辛苦了{:4_190:}

马黑黑 发表于 2024-7-28 18:41

红影 发表于 2024-7-28 17:24
我算好的翻页,肯定下一个帖子就是翻页啊

果然。测算精准

马黑黑 发表于 2024-7-28 18:42

红影 发表于 2024-7-28 17:31
黑黑的讲解很详细,每次学习都有新的收获

这个是比较详细的教程吧,知识点估计会相对全面

红影 发表于 2024-7-28 22:43

马黑黑 发表于 2024-7-28 18:41
果然。测算精准

这个不用测啊,直接看一下就知道了{:4_173:}

红影 发表于 2024-7-28 22:44

马黑黑 发表于 2024-7-28 18:42
这个是比较详细的教程吧,知识点估计会相对全面

是的,跟着这个学习,会比较系统点。

马黑黑 发表于 2024-7-28 22:53

红影 发表于 2024-7-28 22:43
这个不用测啊,直接看一下就知道了

这么厉害

马黑黑 发表于 2024-7-28 22:54

红影 发表于 2024-7-28 22:44
是的,跟着这个学习,会比较系统点。

{:4_181:}

南无月 发表于 2024-7-29 09:25

马黑黑 发表于 2024-7-28 11:08
本页的两个讲义就有冲突:都运行里面的示例的话就会发现。

{:4_190:}

南无月 发表于 2024-7-29 09:25

高楼万丈平地起

南无月 发表于 2024-7-29 09:26

庭院深深深几许

南无月 发表于 2024-7-29 09:27

花潮每页楼层多{:4_173:}

南无月 发表于 2024-7-29 09:27

多回几贴帮翻 页

竹溪 发表于 2024-7-29 09:38

小白来占位学习{:4_204:}

马黑黑 发表于 2024-7-29 13:41

竹溪 发表于 2024-7-29 09:38
小白来占位学习

{:4_190:}

马黑黑 发表于 2024-7-29 13:41

南无月 发表于 2024-7-29 09:25
高楼万丈平地起

{:4_173:}
页: 1 2 [3] 4 5 6 7 8 9 10 11 12
查看完整版本: 小白音画帖教程(完结)