大家好,我是阿潘
今天来分享一个实战的教程哈
目标:复现 b 站视频中出现人物时,弹幕不会遮挡人物的效果
相信经常刷 b 站视频的小伙伴,应该能注意到网友发的弹幕遇到人物时,并不会遮挡住人。
其实大部分一眼就能想到这个背后的技术大概是如何实现的
例如:画面肯定将人物区域截取出来,将人设置在最顶层,弹幕经过人体的时候,不要覆盖到
那么我们也去复现一下这个效果吧
查看页面背后是如何实现的
假设你使用的谷歌浏览器,打开一个弹幕比较多的 《鸡你太美》 艺术作品。
F12 查看网页的源码,在element 栏目下 ctrl f ,并输入 -webkit-mask-image 回车两次即可看到下图的页面(如果没有找到,可以尝试换其他浏览器,没有找到规律的时候可以多看几次)
可以看到标红的框内,在最左边的框里面已经出现了知名舞蹈动作 《铁山靠》
此时可以直接把值复制出来(当然也可以选择另存到本地):
代码语言:javascript复制data:image/svg xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKIHdpZHRoPSI2NjhweCIgc3R5bGU9InRyYW5zZm9ybTpzY2FsZSgxLDEuMDAxKTsiIGhlaWdodD0iMzc1Ljc1cHgiIHZpZXdCb3g9IjAgMCAzMjAuMDAwMDAwIDE4MC4wMDAwMDAiCiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0Ij4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsMTgwLjAwMDAwMCkgc2NhbGUoMC4xMDAwMDAsLTAuMTAwMDAwKSIKZmlsbD0iIzAwMDAwMCIgc3Ryb2tlPSJub25lIj4KPHBhdGggZD0iTTAgOTA1IGwwIC04OTUgNTA2IDAgYzQwMCAwIDUwNSAzIDUwMSAxMyAtMiA2IDUgMjcgMTYgNDYgMTcgMjkgMjEgNTUgMjQgMTQ5CjYgMjM0IDM3IDM0MiAxMzAgNDU2IDI2IDMyIDY0IDg4IDgzIDEyNSBsMzUgNjYgLTcyIDc3IGMtNDAgNDMgLTczIDg0IC03MyA5MgowIDE4IDY0IDk5IDEyMyAxNTggNDQgNDIgMTQ1IDEwMCAyMDAgMTEyIDIzIDUgMjcgMTEgMjcgNDEgMCAyNyA3IDM5IDMzIDU5CjM4IDI5IDUzIDMxIDEwOSAxNCA0MyAtMTMgODggLTU4IDg4IC04OSAwIC0xMSAtOSAtNDAgLTIwIC02NSAtMjIgLTQ4IC0yMAotNzEgMTEgLTExNCAxNSAtMjAgMjAgLTQ2IDIyIC0xMzUgMiAtMTAwIDAgLTExNCAtMjMgLTE2MCAtMTcgLTM0IC0zMyAtNTEKLTUwIC01NiAtMjEgLTUgLTI1IC0xMCAtMjIgLTM5IDEgLTE5IDExIC00NCAyMiAtNTUgMTAgLTExIDM1IC02MSA1NSAtMTEwIDIwCi01MCA0MyAtMTAzIDUyIC0xMjAgMjcgLTU0IDYyIC0xNzYgNzQgLTI1OSA2IC00NCAyMCAtMTAzIDMwIC0xMjkgMTAgLTI3IDE1Ci01NSAxMiAtNjMgLTQgLTEyIDg5IC0xNCA2NTEgLTE0IGw2NTYgMCAwIDg5NSAwIDg5NSAtMTYwMCAwIC0xNjAwIDAgMCAtODk1eiIvPgo8cGF0aCBkPSJNMTM1OCA1ODIgYy0yNiAtMTUgLTc0IC01MyAtMTA3IC04NCAtNTMgLTUxIC02MCAtNjMgLTcwIC0xMTUgLTIyIC0xMTcgLTMxCi0xNTkgLTQxIC0yMDggLTggLTM2IC04IC01OSAtMSAtNzkgNiAtMTUgMTEgLTQxIDExIC01NyBsMCAtMjkgMzIwIDAgMzIwIDAgMAo1MCBjMCAzNiAtMTMgODQgLTQ2IDE2NyAtMjUgNjUgLTUwIDEyOSAtNTUgMTQ0IC02IDE0IC01NiA3MyAtMTEyIDEzMiAtMTE3CjEyMyAtMTM0IDEyOSAtMjE5IDc5eiIvPgo8L2c Cjwvc3ZnPgo=
另存到本地,只需选择 network --> name (找 data:image/svg) --> preview --> 出现的图片右键另存即可
PS:这里证明大家的猜想是对的,后台的页面处理确实添加了对人物区域进行特殊操作。
同时注意到这个样式的 css 属性: -webkit-mask-image(实现的功能:To apply a mask over an image.)
复现效果
整体实现思路:
1、将 mask 保存到本地 或者 将图片的base64编码保存
2、将原图保存,这里我没有找到,所以直接截图下来了
3、将原图、弹幕和mask 组合起来
如果是将图片下载到本地 把 -webkit-mask-image: url() 中的值换成 图片路径即可
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.video {
width: 668px;
height: 376px;
position: relative;
background-color: black;
-webkit-mask-image: url("data:image/svg xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKIHdpZHRoPSI2NjhweCIgc3R5bGU9InRyYW5zZm9ybTpzY2FsZSgxLDEuMDAxKTsiIGhlaWdodD0iMzc1Ljc1cHgiIHZpZXdCb3g9IjAgMCAzMjAuMDAwMDAwIDE4MC4wMDAwMDAiCiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0Ij4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsMTgwLjAwMDAwMCkgc2NhbGUoMC4xMDAwMDAsLTAuMTAwMDAwKSIKZmlsbD0iIzAwMDAwMCIgc3Ryb2tlPSJub25lIj4KPHBhdGggZD0iTTAgOTA1IGwwIC04OTUgNzA4IDAgNzA3IDAgMSAxNTMgYzAgODMgNCAxODUgOCAyMjUgNyA2NyA2IDcyIC0xMiA3MiAtMTEgMAotMjUgNyAtMzIgMTUgLTcgOCAtMTggMTUgLTI1IDE1IC0xOSAwIC0yNiAyNiAtMzIgMTEwIC0zIDQ5IC0xNSAxMDEgLTM0IDE0OQotMTYgNDAgLTI5IDg3IC0yOSAxMDMgMCAzNCA1NSAxNDcgNzUgMTU1IDggMyAxNSAxNSAxNSAyNyAwIDI1IDYxIDE1NiA5MSAxOTUKMTEgMTQgMzggNDAgNjAgNTggNDYgMzcgOTkgMTA5IDk5IDEzNyAwIDExIC02IDI3IC0xNCAzNSAtMjYgMzAgLTg2IDE1MyAtODYKMTc3IDAgMTMgMTYgNDEgMzYgNjQgbDM2IDQwIDEwNCAwIDEwNCAwIDM4IC0zNCBjMzIgLTMwIDM3IC00MCAzNiAtNzggLTEgLTI1Ci0xMiAtNjQgLTI3IC05NCAtMjUgLTUwIC0yNSAtNTAgLTcgLTkxIDEzIC0yOSAzNiAtNTMgNzcgLTgxIDE0NyAtMTAxIDIyNgotMjQzIDI0MCAtNDI4IDcgLTEwMiAtNiAtMTQ4IC01MCAtMTcwIC01NiAtMjggLTY3IC00NCAtNjcgLTkxIDAgLTUwIC0yMSAtOTcKLTUwIC0xMTMgLTE4IC0xMCAtMjAgLTIxIC0yMCAtMTQ1IDAgLTk3IC01IC0xNTYgLTIwIC0yMTcgLTEwIC00NiAtMjIgLTEwNwotMjYgLTEzNSBsLTcgLTUzIDY1MiAwIDY1MSAwIDAgODk1IDAgODk1IC0xNjAwIDAgLTE2MDAgMCAwIC04OTV6Ii8 CjwvZz4KPC9zdmc Cg==") ;
-webkit-mask-size: 668px 376px;
}
.bullet {
position: absolute;
font-size: 20px;
color: white;
animation: ani 5s linear infinite;
}
.showBullet {
position: absolute;
font-size: 20px;
color: red;
animation: show 5s linear infinite;
}
@keyframes ani {
0% {
transform: translateX(668px);
}
100% {
transform: translateX(-668px);
}
}
@keyframes show {
0% {
opacity: 0;
}
10% {
opacity: 1;
}
100% {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="video">
<div class="bullet" style="left: 100px; top: 120px;">鸡你太美,鸡你太美</div>
<div class="bullet" style="left: 200px; top: 60px;">小黑子,哥哥下蛋你别吃</div>
<div class="bullet" style="left: 500px; top: 60px;">食不食油饼</div>
<div class="bullet" style="left: 300px; top: 140px;">鸡哥</div>
<div class="bullet" style="left: 400px; top: 100px;">铁山靠</div>
<div class="showBullet" style="left: 320px; top: 20px;">完结撒花</div>
<div class="showBullet" style="left: 340px; top: 50px;">泪目</div>
</div>
</body>
</html>
声明,我对前端了解并不多,只了解一点基础,如果有误,欢迎指正。下面是我的一点浅薄的认识。
上面的 html 实现的功能
1、首先看下 body 部分,定义文档的主体。body 里面包含了一个 video 属性的 div (区域)
2、 div 的属性是 video,所以查看一下上面的 .video ,里面定义了 区域的宽高、背景色以及将人物区域遮挡住的 -webkit-mask-image
<div> 标签定义 HTML 文档中的一个分隔区块或者一个区域部分
3、div 内部嵌套的 div 属性 bullet、showBullet,用于显示弹幕
综合起来就是上面 html 创建了一个区域,区域的背景黑色,并将中间的人物区域遮挡(mask)掉,这样子弹幕不会在创建的区域上,以实现弹幕不遮挡人物的效果。
效果是这样的:
最后将原始图片添加到画面中
至此,我们就实现了 B 站同款的不遮挡人物的弹幕。
PS:html 文件打开方式选择浏览器即可查看到上图效果
参考资料
https://juejin.cn/post/7141012605535010823
https://blog.csdn.net/qq_37669585/article/details/126829000