T台人生
<style>#mydiv {
margin: 30px 0 30px calc(50% - 721px);
width: 1280px;
height: 768px;
background: url('https://638183.freep.cn/638183/t24/4/tt1.jpg') no-repeat center/cover;
box-shadow: 0 0 6px rgba(0,0,0,.6);
user-select: none;
z-index: 1;
position: relative;
--pos: 0.1%;
}
#mydiv::after {
position: absolute;
content: '';
inset: 0;
background: url('https://638183.freep.cn/638183/t24/4/tt2.jpg') no-repeat center/cover;
-webkit-mask: linear-gradient(to top right, red var(--pos), transparent calc(var(--pos) + 5%), transparent);
}
#player {
position: absolute;
left: calc(50% - 61px);
top: -61px;
cursor: pointer;
transition: 1.2s;
z-index: 2;
animation: rot 6s linear infinite var(--state);
}
#player:hover { filter: drop-shadow(0 0 50px fuchsia); }
#vid {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
-webkit-mask: linear-gradient(to top right, red 90%, transparent 91%, transparent 0);
mix-blend-mode: screen;
}
@keyframes rot {
to { transform: rotate(1turn); }
}
</style>
<div id="mydiv">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1340764398" autoplay loop></audio>
<video id="vid" src="https://img.tukuppt.com/video_show/2418175/00/16/47/5ea1bb1bbf5ad.mp4" autoplay loop muted></video>
<img id="player" alt="" title="播放/暂停" src="https://638183.freep.cn/638183/t23/btn/plum.png" />
</div>
<script>
var zStep = 0.2, zVal = 0, zDo = false;
zMask = () => {
zVal += zStep;
if(zVal > 100 || zVal < -5) zStep = -zStep;
setTimeout( () => {
mydiv.style.setProperty('--pos', zVal + '%');
if(zDo) zMask();
}, 20);
};
mState = () => {
mydiv.style.setProperty('--state', ['running','paused'][+aud.paused]);
player.title = '点击' + ['暂停','播放'][+aud.paused];
aud.paused ? vid.pause() : vid.play();
zDo = aud.paused;
};
mydiv.onmouseover = (e) => {
if(e.target.id.toLowerCase() !== 'mydiv' || aud.paused) return;
zDo = true;
zMask();
};
mydiv.onmouseout = () => zDo = false;
aud.oncanplay = aud.onplaying = aud.onpause = () => mState();
player.onclick = () => aud.paused ? aud.play() : aud.pause();
</script>
<h2>帖子代码</h2>
<div class="hE"><pre>
<style>
#mydiv {
margin: 30px 0 30px calc(50% - 721px);
width: 1280px;
height: 768px;
background: url('https://638183.freep.cn/638183/t24/4/tt1.jpg') no-repeat center/cover;
box-shadow: 0 0 6px rgba(0,0,0,.6);
user-select: none;
z-index: 1;
position: relative;
--pos: 0.1%;
}
#mydiv::after {
position: absolute;
content: '';
inset: 0;
background: url('https://638183.freep.cn/638183/t24/4/tt2.jpg') no-repeat center/cover;
-webkit-mask: linear-gradient(to top right, red var(--pos), transparent calc(var(--pos) + 5%), transparent);
}
#player {
position: absolute;
left: calc(50% - 61px);
top: -61px;
cursor: pointer;
transition: 1.2s;
z-index: 2;
animation: rot 6s linear infinite var(--state);
}
#player:hover { filter: drop-shadow(0 0 50px fuchsia); }
#vid {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
-webkit-mask: linear-gradient(to top right, red 90%, transparent 91%, transparent 0);
mix-blend-mode: screen;
}
@keyframes rot {
to { transform: rotate(1turn); }
}
</style>
<div id="mydiv">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1340764398" autoplay loop></audio>
<video id="vid" src="https://img.tukuppt.com/video_show/2418175/00/16/47/5ea1bb1bbf5ad.mp4" autoplay loop muted></video>
<img id="player" alt="" title="播放/暂停" src="https://638183.freep.cn/638183/t23/btn/plum.png" />
</div>
<script>
var zStep = 0.2, zVal = 0, zDo = false;
zMask = () => {
zVal += zStep;
if(zVal > 100 || zVal < -5) zStep = -zStep;
setTimeout( () => {
mydiv.style.setProperty('--pos', zVal + '%');
if(zDo) zMask();
}, 20);
};
mState = () => {
mydiv.style.setProperty('--state', ['running','paused'][+aud.paused]);
player.title = '点击' + ['暂停','播放'][+aud.paused];
aud.paused ? vid.pause() : vid.play();
zDo = aud.paused;
};
mydiv.onmouseover = (e) => {
if(e.target.id.toLowerCase() !== 'mydiv' || aud.paused) return;
zDo = true;
zMask();
};
mydiv.onmouseout = () => zDo = false;
aud.oncanplay = aud.onplaying = aud.onpause = () => mState();
player.onclick = () => aud.paused ? aud.play() : aud.pause();
</script>
</pre></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);
</script>
本帖最后由 马黑黑 于 2024-8-4 17:57 编辑
动态效果描述:初始时,呈现的是视频融合到帖子背景图像的样貌。在音乐正常播放的前提下,设备指针移动到帖子上但不是播放器之上时(触屏设备点击一下播放器之外的帖子界面),帖子的::after伪元素呈现遮罩特效,伪元素的背景图片与帖子界面以反斜杠对角线方式来回切换(属于转场特效)。设备指针离开帖子界面或移动到播放器之上(触屏设配使用点击操作,点击目标是帖子外围或播放器<这会暂停或播放音乐>)不会触发转场特效。
实现方法简述:
::after 伪元素使用CSS属性 -webkit-mask 设计一个线性渐变的遮罩样式,代码在 18 行。渐变方向自左下角到右上角,红色色标终止于 var(--pos),意思是--pos 这一部分遮罩下的源图案是可见的,--pos 开始时是 0.1%(第10行),然后交给JS动态管理。
代码第50行, var zStep = 0.2, zVal = 0, zDo = false; ,声明了三个JS变量,zStep 是步进值,zVal 是 --pos 要使用的变量值,zDo 是转场依据,一个布尔变量。这三个变量的共同作用操作转场特效。
函数 zMask() ,代码在 50~58 行。函数每次执行,均会将 zVal 的现值加上步进值 zStep(代码52行),当 zVal 大于 100 或少于 -5 时则让 zStep 值变为正负互反,这样可以保证遮罩红色色标终止值在 -5~100 之间来回切换,代码在 53 行。然后加入一个定时器 setTimeout,每隔 20ms 给CSS变量 --pos 赋值一次,并递归执行 zMast() 函数以达到有条件的“永动”目的。
帖子容器的设备指针移入事件触发 zMask() 函数的执行,代码在 65~69行。其中,66行给出一个条件,鼠标指针不在容器自身的直接上方(比如在播放器上面)或音乐暂停中时不触发函数的执行。有朋友可能会问,那视频呢?视频被 ::after 遮挡了,设备指针没有触碰到视频,小播则设置了 z-index 层级属性,它在 ::after 之上层。
帖子容器的设备指针移出终止 zMak() 函数的运行,代码在70 行。
JS代码看似复杂,实则简单,弄懂逻辑关系的处理便可。
{:4_170:}想说这个应该有个说明了吧。。这么难的JS双控。。
两个图片组成,背景图片是一群女生。。
最上方的图片是个舞台,设计一个动态线性渐变。。。。
神奇的是,视频具有上层图片的线性渐变动态。。
同时运行渐变或者同时停止,完全同步。。{:4_173:} 关键 问题是渐变的设计好复杂啊。。
看代码图片和视频渐变全部用JS完成。。我是根本看不懂,烧脑。。{:4_173:}
鼠标移上贴子,渐变开始
鼠标移出贴子,渐变立即停止于当前位置。。(此时可以看到一种神奇的效果)
鼠标如果不移出贴子,触碰到小播,渐变也停止(是否可以理解为小播把渐变层遮挡,所以效果与移出一样)
艾玛,这个新效果是有得学了。。
整体变化越来越神奇,画面渐变之后越来越自然,白老师就是最强大脑{:4_170:} 这个转场效果很奇妙,明明是伪元素的遮罩效果,看起来像视频被卷走了似的{:4_173:} 视频也用遮罩去掉了logo,这个巧妙{:4_187:} 还有鼠标触碰效果。黑黑带来的都是新效果呢{:4_199:} 南无月 发表于 2024-8-4 17:36
想说这个应该有个说明了吧。。这么难的JS双控。。
有滴有滴,看三楼 南无月 发表于 2024-8-4 17:40
两个图片组成,背景图片是一群女生。。
最上方的图片是个舞台,设计一个动态线性渐变。。。。
确切说:
帖子容器是主图片背景,它原生与视频融合;
帖子伪元素 ::after 是女生群(含男生观众)背景,它通过 -webkit-mask 遮罩与帖子整体产生背景切换。 南无月 发表于 2024-8-4 17:44
关键 问题是渐变的设计好复杂啊。。
看代码图片和视频渐变全部用JS完成。。我是根本看不懂,烧脑。。{:4_1 ...
这里,JS再怎么复杂,都是基于CSS的:函数 mState 联动管理动静,依据音频的暂停/播放;zMask 函数负责遮罩所使用的css变量 --pos 的值的动态变更(-5%~100%);还有帖子容器元素的设备指针移入移出控制JS变量 zDo 的值,移入还触发 zMask 函数的运行。逻辑清晰,能理解逻辑问题就行了。 南无月 发表于 2024-8-4 17:46
艾玛,这个新效果是有得学了。。
整体变化越来越神奇,画面渐变之后越来越自然,白老师就是最强大脑{:4_17 ...
严格来讲不是渐变,是线性渐变用于遮罩 本帖最后由 南无月 于 2024-8-4 19:43 编辑
马黑黑 发表于 2024-8-4 19:32
有滴有滴,看三楼
看到了,有朋友可能会问,那视频呢?视频被 ::after 遮挡了,设备指针没有触碰到视频,小播则设置了 z-index 层级属性,它在 ::after 之上层。
这一句还在思考中。。。 红影 发表于 2024-8-4 19:28
这个转场效果很奇妙,明明是伪元素的遮罩效果,看起来像视频被卷走了似的
这是层级关系问题:
帖子容器和视频融为一体,它们是一个单位;伪元素 ::after 自带背景,是另一个单位。
伪元素 ::after 使用遮罩技术,反斜杠对角线渐变的红色位于左下,是伪元素背景图片显示的部分,它依据 --pos 这个 CSS变量 值实现动态效果—— --pos 变量值越大,伪元素显示的背景图区域越宽,遮住第一个单位的面积跟随改变。 红影 发表于 2024-8-4 19:31
视频也用遮罩去掉了logo,这个巧妙
遮猫技术不止一种{:4_170:} 南无月 发表于 2024-8-4 19:41
看到了,有朋友可能会问,那视频呢?视频被 ::after 遮挡了,设备指针没有触碰到视频,小播则设置了 z-in ...
今后的小白课程会讲到伪元素,这里提前吱一声。
::after 伪元素层级很高,宿主元素之下,所有的子元素都在 ::after 的底下。 红影 发表于 2024-8-4 19:32
还有鼠标触碰效果。黑黑带来的都是新效果呢
选择器:hover 不是新内容吧 马黑黑 发表于 2024-8-4 19:35
确切说:
帖子容器是主图片背景,它原生与视频融合;
这算是明白了。。。
开始状态其实上层观众是全遮状态,完全看不到。。
所以此时看到的是下面的背景加视频
当线性渐变动态开始的时候,就是上层观众图逐渐显示。。。
下面的视频和背景逐渐被遮住。。。