让看板娘唱歌

52 Views 

前言

不要看二小姐这么萌,她可是吸血鬼哦~如果一直调戏她的话,一定会暴走的吧,怎么做到这一点呢?

预期效果:点击二小姐15次之后,播放《緋色月下》,同时实时播放歌词。

资源如下:

歌词自动播放

本地服务器

为了网页代码简洁以及便于更换,使用Ajax加载歌词。同时为了便于开发,首先在本地进行实验。

由于Ajax无法读取文件,所以需要在本地搭建一个简易的HTTP服务器,推荐使用 MiniWebServer

设置端口号和根目录后,在浏览器输入 127.0.0.1:端口号 即可。

Ajax获取歌词并生成数组

有的lrc歌词会附有提供者信息,需要手动删除。

我是从网易云中下载的歌曲,分享一个从网易云获得歌词的方法:https://www.jianshu.com/p/63bd947d982a

下边是一个典型的lrc文件的内容:

[00:01.200]私の中の
[00:01.800]私の中の
[00:02.800]私の中の
[00:03.600]私が
[00:04.410]ひとつの
[00:04.900]ひとつの
[00:05.100]単語を
[00:05.910]何度も
[00:06.300]何度も
[00:06.600]何度も
[00:07.500]何度も

解析文档的基本思路是:首先按行分割,然后从前后分别提取时间与歌词。以下是生成歌词数组的代码:

<head><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script></head>  //不要忘了引入jQuery
var lyric = new Array();
$.ajaxSettings.async = false;  //$.get默认是异步进行,会使得歌词还没有加载好就开始执行下面的代码,从而报错。此行暂时禁止异步。
$.get('1.lrc', function (data) {
     var item = data.split('\n');  //按回车分割文本
     $.each(item, function (i, str) { //第一个参数是序号,第二个是内容
    var time = str.substring(str.indexOf('[') + 1, str.indexOf(']')).split(':'); //获取[和]的位置,剪切出中间的时间
    var lyr = str.substring(str.indexOf(']') + 1);
    lyric.push({
         t: (time[0] * 60 + parseFloat(time[1])).toFixed(2),  //换算成秒,同时保留两位小数(毕竟0.1 + 0.2 === 0.30000000000000004)
         l: lyr
        });
    });
});
$.ajaxSettings.async = true;  //恢复异步

在本地预览效果

<body> 中添加如下元素:

<ul id='showlyric' style='list-style: none;'></ul>
<audio id="bgMusic" src="1.mp3" preload></audio>
<button>play</button>

然后再添加如下脚本:

var music = document.getElementById("bgMusic");
$.each(lyric, function (i, item) {
    $("#showlyric").append('<li style="display:none;">' + item.l + '</li>');  //将歌词添加到ul中
});
$('button').click(function () {  //播放音乐
    music.play();
    music.volume = 0.2;
    interval = setInterval("counttime()", 30);  //每30毫秒检测一次歌词。由于《緋色月下》歌词太密集了,所以间隔必须这么短。
});
var lyricNo = 0;  //用于遍历歌词
function counttime() {
    if (music.currentTime >= lyric[lyricNo].t && lyricNo < lyric.length - 1) {  //歌词不到最后一句时
        $('#showlyric li:eq(' + lyricNo + ')').css('display', 'block').siblings().css('display', 'none');  //显示当前歌词,隐藏其他歌词
        lyricNo++;
    }
    else if (lyricNo == lyric.length - 1) {  //歌词到了最后一句,准备收尾工作
        $('#showlyric li:eq(' + lyricNo + ')').css('display', 'block').siblings().css('display', 'none');
        lyricNo = 0;  //重置计数器
        clearInterval(interval);  //停止重复执行
        interval2 = setInterval(() => {
            if (music.currentTime == music.duration) {  //歌曲播放完毕
                music.load();  //重新加载歌曲,相当于重置播放进度
                clearInterval(interval2); //停止重复执行
            }
        }, 400);
    }
}

打开浏览器测试,点击 play 按钮,效果如下:

适配到博客

将上述代码包装成函数,保存到js文件中,将其在head中引入,然后在看板娘的div之后引用。

写入主题的header.php中
写入主题的footer.php中
挂载音乐的audio随便丢到前面的某个地方

在看板娘div中,我复制了一个 message 的div,专门用于歌词播放

#messageegg {
    border: 1px solid rgba(128, 97, 63, 0.144);
    background-color: rgba(110, 91, 39, 0.651);
    box-shadow: 0 3px 15px 2px rgba(255, 137, 137, 0.2);
}

修改一下新 message 的style,更暗黑了

function colorfulegg() {
    lyric = new Array();
    music = document.getElementById("bgMusic");
    $.ajaxSettings.async = false;
    $.get('/wp-content/uploads/2019/09/UnderTheDeepRedMoon.lrc', function (data) { //歌词地址
        var item = data.split('\n');
        $.each(item, function (i, str) {
            var time = str.substring(str.indexOf('[') + 1, str.indexOf(']')).split(':');
            var lyr = str.substring(str.indexOf(']') + 1);
            lyric.push({
                t: (time[0] * 60 + parseFloat(time[1])).toFixed(2),
                l: lyr
            });
        });
    });
    $.ajaxSettings.async = true;
    $('#landlord').click(function () {  //点击16次芙兰就生气啦!
        if (countclick > 15) {
            music.play();
            music.volume = 0.2;
            interval = setInterval("counttime()", 30);
            $('#messagenormal').animate({ left: '1000px' }, 0);  //用于隐藏平时的对话框。
            $('.hide-button').animate({ right: '-1000px' }, 0);  //由于显示消息的函数修改它的透明度,这里将其移出屏幕来“障眼”
            countclick = 0;  //重置点击次数
        }
        else if (countclick == 15) {
            showMessage('我要生气了哦?', 1000);
            countclick++;
        }
        else {
            countclick++;
        }
    });
}
var lyricNo = 0;
var countclick = 0;  //统计用户的点击次数
function counttime() {
    if (music.currentTime >= lyric[lyricNo].t && lyricNo < lyric.length - 1) {
        showMessage2(lyric[lyricNo].l, 7000);
        lyricNo++;
        countclick = 0;  //不停的清零,防止用户狂点芙兰造成的可能的bug
        $('.message p').css("color", "#f30000");
        $('.message p').animate({ left: '5px' }, 50);  //让歌词抖动起来
        $('.message p').animate({ left: '-5px' }, 50);
        $('.message p').animate({ left: '5px' }, 50);
        $('.message p').animate({ left: '-5px' }, 50);
        $('.message p').animate({ left: '0px' }, 50);
    }
    else if (lyricNo == lyric.length - 1) {
        showMessage2(lyric[lyricNo].l, 7000);
        $('.message p').css("color", "#f30000");
        $('.message p').animate({ left: '5px' }, 50);
        $('.message p').animate({ left: '-5px' }, 50);
        $('.message p').animate({ left: '5px' }, 50);
        $('.message p').animate({ left: '-5px' }, 50);
        $('.message p').animate({ left: '0px' }, 50);
        countclick = 0;
        lyricNo = 0;
        clearInterval(interval);
        interval2 = setInterval(() => {
            if (music.currentTime == music.duration) {
                music.load();
                countclick = 0;
                $('#messagenormal').animate({ left: '-10px' }, 0);   //恢复正常的消息框
                $('.hide-button').animate({ right: '0px' }, 0);
                clearInterval(interval2);
            }
        }, 400);
    }
}

同时修改看板娘的 message.js

function showMessage2(text, timeout) {
    if (Array.isArray(text)) text = text[Math.floor(Math.random() * text.length + 1) - 1];
    //console.log('showMessage', text);
    $('#messageegg').stop();
    $('#messageegg').html('<p>' + text + '</p>').fadeTo(200, 1);
    if (timeout === null) timeout = 5000;
    hideMessage2(timeout);
function hideMessage2(timeout) {
    $('#messageegg').stop().css('opacity', 1);
    if (timeout === null) timeout = 5000;
    $('#messageegg').delay(timeout).fadeTo(200, 0);
}
//专门生成歌词对话框

好了,到此所有设置均已完成。下面看看效果吧:

相关推荐

1 条评论

  1. 韩大妈 韩大妈说道:

    xiaohuli
    我只是一只小狐狸

发表评论

电子邮件地址不会被公开。 必填项已用*标注

   
隐藏