马黑黑 发表于 2023-2-26 07:55

花下醉(4首)

本帖最后由 马黑黑 于 2023-2-26 08:45 编辑 <br /><br /><style>
#papa {
        margin: -80px 0 0 calc(50% - 593px);
        width: 1024px;
        height: 640px;
        background: lightblue url('https://638183.freep.cn/638183/t23/webp/hxz.webp') no-repeat center/cover;
        box-shadow: 3px 3px 20px #000;
        position: relative;
        user-select: none;
        z-index: 1;
        --state: paused;
}
#fly {
        position: absolute;
        left: 0;
        width: 360px;
        height: 200px;
        animation: fly 100s infinite alternate var(--state);
}
.mplayer {
        --tt: 6s;
        position: absolute;
        left: 0;
        width: 200px;
        height: 200px;
        border-radius: 50%;
        transform: perspective(1000px) rotateX(45deg) rotateY(30deg);
        animation: rot var(--tt) infinite var(--state);
        cursor: pointer;
        transition: .45s;
}
.mplayer:hover { filter: drop-shadow(0 0 80px green) brightness(200%); }
.mplayer:nth-of-type(2) {
        --tt: 4s;
        left: 210px;
        width: 150px;
        height: 150px;
}
.mplayer:nth-of-type(3) {
        --tt: 2s;
        left: 130px;
        width: 100px;
        height: 100px;
}
#drunken {
        position: absolute;
        bottom: 60px;
        left: 23%;
        mix-blend-mode: multiply;
        cursor: pointer;
}
#btnFs {
        position: absolute;
        left: 50%;
        transform: translate(-50%);
        bottom: 20px;
        width: fit-content;
        height: fit-content;
        padding: 6px;
        border-radius: 6px;
        border: 2px solid snow;
        color: snow;
        display: none;
        cursor: pointer;
}
@keyframes rot { to { transform: perspective(1000px) rotateX(45deg) rotateY(30deg) rotateZ(360deg); } }
@keyframes fly { to { left: calc(50% - 360px); } }
</style>

<div id="papa">
        <div id="fly">
                <img class="mplayer" src="https://638183.freep.cn/638183/t23/1/rose.png" alt="" />
                <img class="mplayer" src="https://638183.freep.cn/638183/t23/1/toui.png" alt="" />
                <img class="mplayer" src="https://638183.freep.cn/638183/t23/1/7sh-1.png" alt="" />
        </div>
        <img id="drunken" src="/static/image/smiley/hcbiaoqing2/130.gif" title="下一首" alt="" />
        <div id="btnFs">全屏观赏</div>
</div>
<audio id="aud"></audio>

<script>
(function() {
        let fs = false, timerId;
        let ypAr = ['38392980','158378','315691','1907058655'];
        let mState = () => papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');
        let playNext = () => {
                aud.src = 'https://music.163.com/song/media/outer/url?id=' + ypAr + '.mp3';
                aud.play();
        }
        let btns = document.querySelectorAll('.mplayer');
        [...btns].forEach((item) => item.onclick = () => aud.paused ? aud.play() : aud.pause());
        aud.addEventListener('play', () => mState());
        aud.addEventListener('pause', () => mState());
        aud.addEventListener('ended', () => playNext());
        drunken.addEventListener('click', () => playNext());
        btnFs.addEventListener('click', () => fs ? document.exitFullscreen() : papa.requestFullscreen());
        document.addEventListener('fullscreenchange', () => document.fullscreenElement !== null ? (fs = true, btnFs.innerText = '退出全屏') : (fs = false, btnFs.innerText = '全屏观赏'));
        papa.addEventListener('mousemove', (e) => {
                clearTimeout(timerId);
                btnFs.style.display = 'block';
                timerId = setTimeout('btnFs.style.display = "none"', 3000);
        });
        playNext();
})();
</script>

马黑黑 发表于 2023-2-26 07:59

帖子代码
<style>
#papa {
        margin: -80px 0 0 calc(50% - 593px);
        width: 1024px;
        height: 640px;
        background: lightblue url('https://638183.freep.cn/638183/t23/webp/hxz.webp') no-repeat center/cover;
        box-shadow: 3px 3px 20px #000;
        position: relative;
        user-select: none;
        z-index: 1;
        --state: paused;
}
#fly {
        position: absolute;
        left: 0;
        width: 360px;
        height: 200px;
        animation: fly 100s infinite alternate var(--state);
}
.mplayer {
        --tt: 6s;
        position: absolute;
        left: 0;
        width: 200px;
        height: 200px;
        border-radius: 50%;
        transform: perspective(1000px) rotateX(45deg) rotateY(30deg);
        animation: rot var(--tt) infinite var(--state);
        cursor: pointer;
        transition: .45s;
}
.mplayer:hover { filter: drop-shadow(0 0 80px green) brightness(200%); }
.mplayer:nth-of-type(2) {
        --tt: 4s;
        left: 210px;
        width: 150px;
        height: 150px;
}
.mplayer:nth-of-type(3) {
        --tt: 2s;
        left: 130px;
        width: 100px;
        height: 100px;
}
#drunken {
        position: absolute;
        bottom: 60px;
        left: 23%;
        mix-blend-mode: multiply;
        cursor: pointer;
}
#btnFs {
        position: absolute;
        left: 50%;
        transform: translate(-50%);
        bottom: 20px;
        width: fit-content;
        height: fit-content;
        padding: 6px;
        border-radius: 6px;
        border: 2px solid snow;
        color: snow;
        display: none;
        cursor: pointer;
}
@keyframes rot { to { transform: perspective(1000px) rotateX(45deg) rotateY(30deg) rotateZ(360deg); } }
@keyframes fly { to { left: calc(50% - 360px); } }
</style>

<div id="papa">
        <div id="fly">
                <img class="mplayer" src="https://638183.freep.cn/638183/t23/1/rose.png" alt="" />
                <img class="mplayer" src="https://638183.freep.cn/638183/t23/1/toui.png" alt="" />
                <img class="mplayer" src="https://638183.freep.cn/638183/t23/1/7sh-1.png" alt="" />
        </div>
        <img id="drunken" src="/static/image/smiley/hcbiaoqing2/130.gif" title="下一首" alt="" />
        <div id="btnFs">全屏观赏</div>
</div>
<audio id="aud"></audio>

<script>
(function() {
        let fs = false, timerId;
        let ypAr = ['38392980','158378','315691','1907058655'];
        let mState = () => papa.style.setProperty('--state', aud.paused ? 'paused' : 'running');
        let playNext = () => {
                aud.src = 'https://music.163.com/song/media/outer/url?id=' + ypAr + '.mp3';
                aud.play();
        }
        let btns = document.querySelectorAll('.mplayer');
        [...btns].forEach((item) => item.onclick = () => aud.paused ? aud.play() : aud.pause());
        aud.addEventListener('play', () => mState());
        aud.addEventListener('pause', () => mState());
        aud.addEventListener('ended', () => playNext());
        drunken.addEventListener('click', () => playNext());
        btnFs.addEventListener('click', () => fs ? document.exitFullscreen() : papa.requestFullscreen());
        document.addEventListener('fullscreenchange', () => document.fullscreenElement !== null ? (fs = true, btnFs.innerText = '退出全屏') : (fs = false, btnFs.innerText = '全屏观赏'));
        papa.addEventListener('mousemove', (e) => {
                clearTimeout(timerId);
                btnFs.style.display = 'block';
                timerId = setTimeout('btnFs.style.display = "none"', 3000);
        });
        playNext();
})();
</script>


马黑黑 发表于 2023-2-26 08:37

全屏、音乐控制均未使用插件,便于大家观察、学习。解释一下JS代码:

83行:两个变量,fs 是 全屏依赖变量,布尔类型(true 或 false);timeId 是定时器依赖变量,setTimeout 定时器清除和启用句柄,控制全屏相关的按钮显示/隐藏的依托。

84行:声明wyy音乐id数组;

85行:自定义函数,音乐控制器的关键帧动画控制预设;

86行 - 89行:自定义函数,播放音乐,随机播放。几个地方会用到它,一是页面打开时(103行),二是一支曲子播放完毕时(94行),三是点击小醉鬼时(95行);

90行:声明音频播放控制器句柄,这是三个“按钮”,所以放入集合变量中;

91行:“按钮”集合点击事件。btns 变量属对象变量,将之变成可操作的数组,所以使用扩展运算符 ... 将其变为数组对象,即[...btns] ,这样就可以用 forEach 方法对数组元素(按钮)进行操作;

92行 - 94行:audio 控件监听事件,各行分别监听 audio 控件的 play(播放)、pause(暂停)和 ended(播放结束)三个事件,前两个事件运行 85 行的 mState() 函数,即驱动播放控制器的状态,后一个事件运行 86 行开始的函数 playNext() 即播放音乐函数;

95行:监听小醉鬼点击事件,运行的是 playNext() 函数。任何时候都可以点击它更换音乐;

96行:监听全屏按钮点击事件,依据 fs 变量值驱动全屏/窗口模式切换;

97行:监听 document 的 fullscreen 事件,即监听文档的全屏事件,若文档有元素处于全屏状态,则令 fs 变量为真,且设置按钮文本为“退出全屏”,反之,若没有元素处于全屏状态,则令 fs 变量为假,且设置按钮文本为“全屏观赏”;

98行 - 102行:监听帖子父元素 papa 的鼠标指针滑过事件,这里要干的事情是,一是清除定时器记录以便重新计时(99行),二是令全屏按钮现身(100行),三是启动定时器(101行),定时器所做的事情是3秒后令全屏按钮消失。这部分,呈现在web中的效果是,鼠标在帖子区域一旦移动,全屏按钮就会华丽现身,如果鼠标指针静止,3秒钟后按钮消失。

103行:运行一次 playNext() 函数,令页面打开时随机播放四支曲子中的一支。

小辣椒 发表于 2023-2-26 09:26

手机测试点击了按钮和小酒鬼,效果不错{:4_187:}

红影 发表于 2023-2-26 09:26

这个帖子信息量很大,黑黑解说得也特别详细。真棒{:4_199:}

小辣椒 发表于 2023-2-26 09:27

黑黑真的千变万化的效果层出不穷,厉害的

小辣椒 发表于 2023-2-26 09:29

三个不一样小图片了

红影 发表于 2023-2-26 09:30

原来这个多首音乐,在四首音乐里随机切换。
ypAr 这句没看懂,为什么这句就能对应音乐id数组?

红影 发表于 2023-2-26 09:33

小醉鬼能换音乐,三个旋转播放器能暂停和播放音乐{:4_187:}

红影 发表于 2023-2-26 09:33

马黑黑 发表于 2023-2-26 08:37
全屏、音乐控制均未使用插件,便于大家观察、学习。解释一下JS代码:

83行:两个变量,fs 是 全屏依赖变 ...

这个讲得真详细,太棒了{:4_199:}

小辣椒 发表于 2023-2-26 09:35

马黑黑 发表于 2023-2-26 08:37
全屏、音乐控制均未使用插件,便于大家观察、学习。解释一下JS代码:

83行:两个变量,fs 是 全屏依赖变 ...

这样的讲解太仔细的,黑黑教授有水平{:4_178:}

马黑黑 发表于 2023-2-26 09:35

红影 发表于 2023-2-26 09:33
这个讲得真详细,太棒了

大概逻辑讲了,细节哪儿不懂的说一声

马黑黑 发表于 2023-2-26 09:35

小辣椒 发表于 2023-2-26 09:26
手机测试点击了按钮和小酒鬼,效果不错

还木起来呀{:5_106:}

马黑黑 发表于 2023-2-26 09:36

红影 发表于 2023-2-26 09:33
小醉鬼能换音乐,三个旋转播放器能暂停和播放音乐

这正常的呀

梦缘 发表于 2023-2-26 09:36

转动的图片,感谢老师的精彩分享,问好!{:4_204:}

梦缘 发表于 2023-2-26 09:36

真不错的代码,感谢分享!{:4_180:}

马黑黑 发表于 2023-2-26 09:36

红影 发表于 2023-2-26 09:26
这个帖子信息量很大,黑黑解说得也特别详细。真棒

重点讲了JS部分,其他的应该都能懂就不讲了

马黑黑 发表于 2023-2-26 09:43

红影 发表于 2023-2-26 09:30
原来这个多首音乐,在四首音乐里随机切换。
ypAr 这句没看懂,为 ...

Math.random() 是JS随机数,其值范围在 0 到 0.999... 之间,如此,Math.random()*ypAr.length 得到的数,在这里,在0 - 3.x 之间,因为数组总数是 4 ;

Math.floor(数字) 往下取整(floor是地板),那么,Math.floor(Math.random()*ypAr.length),得到的是 0 和 3 之间的整数(包含 0 和 3 )。

数组下标从 0 开始,0 是数组的第一个元素,3 是数组的第四个元素。

马黑黑 发表于 2023-2-26 09:45

梦缘 发表于 2023-2-26 09:36
真不错的代码,感谢分享!

上午好

马黑黑 发表于 2023-2-26 09:45

小辣椒 发表于 2023-2-26 09:35
这样的讲解太仔细的,黑黑教授有水平

不嫌啰嗦就好{:5_106:}
页: [1] 2 3 4 5 6
查看完整版本: 花下醉(4首)