午后・时光

【黑师音画帖小白教程】第七 讲:加入音、视频及CSS关键帧动画联动控制机制

位置: 首页 > 马黑教程[ 发布时间: 2024.8.6  作者: 马黑黑  阅读: 120 ]

第七讲:加入音、视频及CSS关键帧动画联动控制机制

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

//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(); //控制视频播放&暂停
};

花括号 {} 包裹起来的三行代码就是函数体代码集合,即 mState() 函数要执行的具体内容。各行内容解释如下:

第5行:这是上一讲的内容,通过JS内置的 元素.style.setProperty('CSS属性名称','CSS属性值') 方法改变我们预定义的CSS变量 --state 的值来达成控制四叶草旋转与否的目的。我们通过帖子容器元素 papa 来传达 --state 变量值,这样可以控制其下所有使用 --state 变量的子元素(前提是子元素CSS代码不给它赋值,具体说就是 --state: running/paused 不能写在子元素选择器里)。

第6行:设置小播提示语,player.title 可以理解为“小播的标题”,title这里是一个特殊标题,鼠标指针移动到其上时弹出的 tiptop 提示语,它等于(=),问,音乐暂停中么?答,若暂停,那么提示语是“播放”,意思是点我播放,若不是暂停中,那么,提示语是“暂停”,意思是点我暂停。

第7行,询问音乐是否暂停中,答,若是,视频暂停,反之,视频播放。

这个 mState() 函数可以根据帖子的情况或自己的设计增删或改变相应内容,实现同一功能比如提示语的确定也可以用不同的方式。不论如何,函数总体功能就是智能地联动控制帖子相应子元素的动作或状态,并通过 audio 音频控件来更智能地操纵这个函数——换言之,通过对音频控件的几个事件的监听来运行 mState() 函数。试看代码:

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

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

如此一来,小播的单击事件就只做一件事情,无需再去管控联动机制的工作:

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

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

<!-- 第一部分 :css代码 -->

<style>
/* 帖子容器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; } }
</style>

<!-- 第二部分 :html代码 父元素带4个子元素 -->

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

<!-- 第三部分 :JS代码 -->

<script>

//联动控制函数
var mState = () => {
	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 = () => mState();

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

</script>

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

返回目录

前一篇: 【黑师音画帖小白教程】第六讲:帖子加入音频并使用旋转的图片“控制”音频
下一篇: 【黑师音画帖小白教程】第八讲:联动控制函数如何管理众多子元素的动态变化

发表评论:

       

评论列表 [0条]

Copyright © 2014 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com