马黑黑 发表于 2023-2-28 07:45

风叶穿行(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>

马黑黑 发表于 2023-2-28 07:45

帖子代码
<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>

马黑黑 发表于 2023-2-28 07:56

播放控制器效果说明:

小球由类名为 ball 的CSS选择器 .ball 设置样式,它们宽高 20*20,彼此间间隔 2px,圆形,背景浅蓝色,不透明度 0.45,相对定位,行内块显示模式,有一个基础阴影。它们是 id="mplayer" 容器的子元素。

小球有 JS 生成,生成过程赋予其调用关键帧动画 flash 的功能,每个小球运行动画的周期时长随机获取,都在一秒之内(会一定概率存在0秒,严谨的话应再加0.1秒)。

而 @keyframes 定义的 flash 关键帧动画,使用盒子阴影实现,一个外阴影,一个内阴影,内外结合以营造扑朔迷离的闪动效果。此外,初始阴影也会在动画过程中产生作用。

马黑黑 发表于 2023-2-28 07:58

思考:如果小球背景色设置为全透明(background: transparent),会得出什么效果?

马黑黑 发表于 2023-2-28 08:05

关于背景音乐:

这是防 8bit 的音乐,就是DOS时代常听到的音源。bit是位的意思,与存储有关,8bit指音源的每一个采样值都有2的8次方(即256)种可能(不一定那么多)。玩过任天堂红白机的朋友对此应有感触。

马黑黑 发表于 2023-2-28 08:07

这个播放控制器闪动效果,猛一看,像是响应音频的东东,其实不是哈。它只是闪动频率偏快,与音乐节拍貌似能踩点而已。

庶民 发表于 2023-2-28 08:29

这样的背景音乐,很感兴趣。

红影 发表于 2023-2-28 09:18

马黑黑 发表于 2023-2-28 07:58
思考:如果小球背景色设置为全透明(background: transparent),会得出什么效果?

那就只剩阴影在闪了?

红影 发表于 2023-2-28 09:21

马黑黑 发表于 2023-2-28 08:07
这个播放控制器闪动效果,猛一看,像是响应音频的东东,其实不是哈。它只是闪动频率偏快,与音乐节拍貌似能 ...

按照随机数 ${Math.random()}s来说,套用的时候,好像也需选用快节奏音乐呢。
你这个音乐跟这个闪动效果配合得特别好{:4_199:}

红影 发表于 2023-2-28 09:31

马黑黑 发表于 2023-2-28 07:56
播放控制器效果说明:

小球由类名为 ball 的CSS选择器 .ball 设置样式,它们宽高 20*20,彼此间间隔 2px ...

看看内外阴影数字不大啊,效果上看觉得阴影很长啊{:4_187:}

红影 发表于 2023-2-28 09:43

红影 发表于 2023-2-28 09:31
看看内外阴影数字不大啊,效果上看觉得阴影很长啊

看错了,@keyframes里的设置还是挺大的{:4_173:}

马黑黑 发表于 2023-2-28 11:55

红影 发表于 2023-2-28 09:31
看看内外阴影数字不大啊,效果上看觉得阴影很长啊

它们串起来的

马黑黑 发表于 2023-2-28 11:56

庶民 发表于 2023-2-28 08:29
这样的背景音乐,很感兴趣。

清朗纯净

马黑黑 发表于 2023-2-28 11:57

红影 发表于 2023-2-28 09:43
看错了,@keyframes里的设置还是挺大的

也没多大,一般大

醉美水芙蓉 发表于 2023-2-28 11:57

马黑黑 发表于 2023-2-28 11:58

红影 发表于 2023-2-28 09:21
按照随机数 ${Math.random()}s来说,套用的时候,好像也需选用快节奏音乐呢。
你这个音乐跟这个闪动效果 ...

可以通过对计算的设计进行调节。也可以有 audio 标签的 timeupdate 事件控制运动频率(不使用关键帧动画)

马黑黑 发表于 2023-2-28 12:01

红影 发表于 2023-2-28 09:18
那就只剩阴影在闪了?

动画的内容只有 @keyframes 里的阴影,其他的,如初始阴影,背景色,是静态的。初始阴影会被大阴影覆盖,背景色则因元素的 opacity 以及 @keyframes 里的内阴影而受到影响。

马黑黑 发表于 2023-2-28 12:02

醉美水芙蓉 发表于 2023-2-28 11:57
欣赏老师佳作!

中午好

绿叶清舟 发表于 2023-2-28 12:13

象电报了

马黑黑 发表于 2023-2-28 12:14

绿叶清舟 发表于 2023-2-28 12:13
象电报了

打给谁呢
页: [1] 2 3 4 5
查看完整版本: 风叶穿行(8bit背景音乐)