风叶穿行(8bit背景音乐)
<style>#papa {
--state: paused;
margin: -80px 0 0 calc(50% - 593px);
display: grid;
place-items: center;
width: 1024px;
height: 640px;
background: lightblue url('https://638183.freep.cn/638183/t23/webp/fyix.webp') no-repeat center/cover;
box-shadow: 6px 3px 20px #000;
user-select: none;
position: relative;
z-index: 1;
}
#mplayer {
position: absolute;
width: fit-content;
height: fit-content;
top: 40px;
cursor: pointer;
}
.ball {
margin: 2px;
width: 20px;
height: 20px;
border-radius: 50%;
background: lightblue;
opacity:.45;
position: relative;
display: inline-block;
box-shadow: -4px -4px 4px blue;
}
#btnFs {
position: absolute;
bottom: 20px;
width: fit-content;
height: fit-content;
padding: 6px;
border-radius: 6px;
border: 2px solid snow;
color: snow;
text-shadow: 1px 1px 1px #000;
display: none;
cursor: pointer;
}
@keyframes flash { to { box-shadow: 0 0 60px 20px blue, -2px -2px 8px snow inset; } }
</style>
<div id="papa">
<div id="mplayer"></div>
<div id="btnFs">全屏观赏</div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1933216917.mp3" autoplay loop></audio>
</div>
<script>
(function() {
let total = 26, fs = false, timerId;
for(i = 0; i < total; i++) {
let span = document.createElement('span');
span.className = 'ball';
span.style.cssText += `
animation: flash ${Math.random()}s infinite alternate var(--state);
`;
mplayer.appendChild(span);
}
let mState = () => papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');
mplayer.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('play', () => mState());
aud.addEventListener('pause', () => mState());
aud.addEventListener('ended', () => playNext());
aud.addEventListener('error', () => {
if(aud.error.code === 4) aud.src = 'http://www.kumeiwp.com/sub/filestores/2023/02/28/466426af58d0bcacee07591638ed5f9a.mp3';
});
papa.addEventListener('mousemove', (e) => {
clearTimeout(timerId);
btnFs.style.display = 'block';
timerId = setTimeout('btnFs.style.display = "none"', 3000);
});
btnFs.addEventListener('click', () => fs ? document.exitFullscreen() : papa.requestFullscreen());
document.addEventListener('fullscreenchange', () => document.fullscreenElement !== null ? (fs = true, btnFs.innerText = '退出全屏') : (fs = false, btnFs.innerText = '全屏观赏'));
})();
</script>
帖子代码
<style>
#papa {
--state: paused;
margin: -80px 0 0 calc(50% - 593px);
display: grid;
place-items: center;
width: 1024px;
height: 640px;
background: lightblue url('https://638183.freep.cn/638183/t23/webp/fyix.webp') no-repeat center/cover;
box-shadow: 6px 3px 20px #000;
user-select: none;
position: relative;
z-index: 1;
}
#mplayer {
position: absolute;
width: fit-content;
height: fit-content;
top: 40px;
cursor: pointer;
}
.ball {
margin: 2px;
width: 20px;
height: 20px;
border-radius: 50%;
background: lightblue;
opacity:.45;
position: relative;
display: inline-block;
box-shadow: -4px -4px 4px blue;
}
#btnFs {
position: absolute;
bottom: 20px;
width: fit-content;
height: fit-content;
padding: 6px;
border-radius: 6px;
border: 2px solid snow;
color: snow;
text-shadow: 1px 1px 1px #000;
display: none;
cursor: pointer;
}
@keyframes flash { to { box-shadow: 0 0 60px 20px blue, -2px -2px 8px snow inset; } }
</style>
<div id="papa">
<div id="mplayer"></div>
<div id="btnFs">全屏观赏</div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1933216917.mp3" autoplay loop></audio>
</div>
<script>
(function() {
let total = 26, fs = false, timerId;
for(i = 0; i < total; i++) {
let span = document.createElement('span');
span.className = 'ball';
span.style.cssText += `
animation: flash ${Math.random()}s infinite alternate var(--state);
`;
mplayer.appendChild(span);
}
let mState = () => papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');
mplayer.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('play', () => mState());
aud.addEventListener('pause', () => mState());
aud.addEventListener('ended', () => playNext());
aud.addEventListener('error', () => {
if(aud.error.code === 4) aud.src = 'http://www.kumeiwp.com/sub/filestores/2023/02/28/466426af58d0bcacee07591638ed5f9a.mp3';
});
papa.addEventListener('mousemove', (e) => {
clearTimeout(timerId);
btnFs.style.display = 'block';
timerId = setTimeout('btnFs.style.display = "none"', 3000);
});
btnFs.addEventListener('click', () => fs ? document.exitFullscreen() : papa.requestFullscreen());
document.addEventListener('fullscreenchange', () => document.fullscreenElement !== null ? (fs = true, btnFs.innerText = '退出全屏') : (fs = false, btnFs.innerText = '全屏观赏'));
})();
</script>
播放控制器效果说明:
小球由类名为 ball 的CSS选择器 .ball 设置样式,它们宽高 20*20,彼此间间隔 2px,圆形,背景浅蓝色,不透明度 0.45,相对定位,行内块显示模式,有一个基础阴影。它们是 id="mplayer" 容器的子元素。
小球有 JS 生成,生成过程赋予其调用关键帧动画 flash 的功能,每个小球运行动画的周期时长随机获取,都在一秒之内(会一定概率存在0秒,严谨的话应再加0.1秒)。
而 @keyframes 定义的 flash 关键帧动画,使用盒子阴影实现,一个外阴影,一个内阴影,内外结合以营造扑朔迷离的闪动效果。此外,初始阴影也会在动画过程中产生作用。 思考:如果小球背景色设置为全透明(background: transparent),会得出什么效果? 关于背景音乐:
这是防 8bit 的音乐,就是DOS时代常听到的音源。bit是位的意思,与存储有关,8bit指音源的每一个采样值都有2的8次方(即256)种可能(不一定那么多)。玩过任天堂红白机的朋友对此应有感触。 这个播放控制器闪动效果,猛一看,像是响应音频的东东,其实不是哈。它只是闪动频率偏快,与音乐节拍貌似能踩点而已。 这样的背景音乐,很感兴趣。 马黑黑 发表于 2023-2-28 07:58
思考:如果小球背景色设置为全透明(background: transparent),会得出什么效果?
那就只剩阴影在闪了? 马黑黑 发表于 2023-2-28 08:07
这个播放控制器闪动效果,猛一看,像是响应音频的东东,其实不是哈。它只是闪动频率偏快,与音乐节拍貌似能 ...
按照随机数 ${Math.random()}s来说,套用的时候,好像也需选用快节奏音乐呢。
你这个音乐跟这个闪动效果配合得特别好{:4_199:} 马黑黑 发表于 2023-2-28 07:56
播放控制器效果说明:
小球由类名为 ball 的CSS选择器 .ball 设置样式,它们宽高 20*20,彼此间间隔 2px ...
看看内外阴影数字不大啊,效果上看觉得阴影很长啊{:4_187:} 红影 发表于 2023-2-28 09:31
看看内外阴影数字不大啊,效果上看觉得阴影很长啊
看错了,@keyframes里的设置还是挺大的{:4_173:} 红影 发表于 2023-2-28 09:31
看看内外阴影数字不大啊,效果上看觉得阴影很长啊
它们串起来的 庶民 发表于 2023-2-28 08:29
这样的背景音乐,很感兴趣。
清朗纯净 红影 发表于 2023-2-28 09:43
看错了,@keyframes里的设置还是挺大的
也没多大,一般大 红影 发表于 2023-2-28 09:21
按照随机数 ${Math.random()}s来说,套用的时候,好像也需选用快节奏音乐呢。
你这个音乐跟这个闪动效果 ...
可以通过对计算的设计进行调节。也可以有 audio 标签的 timeupdate 事件控制运动频率(不使用关键帧动画) 红影 发表于 2023-2-28 09:18
那就只剩阴影在闪了?
动画的内容只有 @keyframes 里的阴影,其他的,如初始阴影,背景色,是静态的。初始阴影会被大阴影覆盖,背景色则因元素的 opacity 以及 @keyframes 里的内阴影而受到影响。 醉美水芙蓉 发表于 2023-2-28 11:57
欣赏老师佳作!
中午好 象电报了 绿叶清舟 发表于 2023-2-28 12:13
象电报了
打给谁呢