用Hexo的live2d插件做了一个可以聊天的小宠物

今天觉得我的博客有点小小的简陋,就做了一点美化工作

主要使用hexo的live2d插件(感谢作者),搭配上机器人对话api,做了一个可以聊天的小宠物。

效果图

本来是在live2d的github主页上看到了有dialog这个配置选项,一开始以为就是可以配置一个交互式的聊天窗口。

dialog配置

dialog配置

然后发现使用一言api只是过个几秒钟给你弹一句话看看,也没有其他的api选项可以配置,在百度上一搜好像也没有多少人写过关于这个dialog的用法。

然后我看了下它生成的源码:

组件结构

组件结构

live2d-widget是整个组件的div,里面有一个live2d-widget-dialog就是卡通形象上面的那个对话框,live2dcanvas就是画卡通形象的画布。如果要让对话框显示文字,就是修改class名为live2d-widget-dialog的div的innerHtml。

既然没有提供相关的对话api,那就手动做一个吧。

live2d安装

你既然看到了这篇文章,我就假设你知道live2d是什么 (看板娘) 。在hexo安装live2d插件的方式很简单:

npm install --save hexo-helper-live2d

然后选一个心仪的模型安装,模型的预览可以参考插件作者的博客:

https://huaji8.top/post/live2d-plugin-2.0/

模型的名称参考:

https://github.com/xiazeyu/live2d-widget-models

npm install --save 模型名称

然后在hexo根目录下的_config.yml中配置live2d:

#live2d
live2d:
    enable: true
    scriptFrom: local
    model: 
        use: live2d-widget-model-wanko #模型选择
    display: 
        position: right #模型位置
        width: 200      #模型宽度
        height: 200     #模型高度
        hOffset: 20     #水平偏移
        vOffset: 100    #垂直偏移
    mobile: 
        show: false     #是否在手机端显示
    dialog:
        enable: true    #启用对话框
        hitokoto: false

具体的配置可以参考:

https://l2dwidget.js.org/docs/class/src/index.js~L2Dwidget.html#instance-method-init

组件改造

在模型下方增加一个input输入框

因为我把模型放在了右边,并且水平偏移和垂直偏移都是已知的。
要在它的下方增加一个输入框,找到hexo中/themes/你的主题/layout/layout.ejs文件,在里面body标签中末尾添加:

<div id="chat_input">
    <input id="question" type="text" placeholder="陪我聊聊天吧" onkeypress="return onKeyPress(event)"/>
</div>

然后在文件尾部配置它的样式:

<style> 
#chat_input{
    width: 200px;
    height: 40px;
    position: fixed;
    bottom: 80px;
    right: 20px;
} 

#question{
    border: none;/*取消输入框边框*/
    border-bottom: 1px #aaaaaa solid;/*设置下边框*/
    background-color: transparent;/*背景透明*/
    padding: 5px;
}

/*手机端不显示*/
@media screen and (max-width: 480px) {
    #chat_input{
        display: none;
    }
    #live2d-widget{
        display: none;
    }
}
</style>

输入框就做好了。

聊天逻辑实现

要做到智能聊天需要一个聊天机器人的api,有图灵机器人、小i机器人等可以选择。

我这里用的是茉莉机器人,就不推荐大家使用了,小小吐槽一下这个开发者好像不是很懂后端api,鉴权方式有点奇怪 (人间迷惑行为大赏)

获取了api之后就可以做输入框的事件处理:(因为我的主题不包含jQuery我也懒得引,就用的原生js)

//在聊天框按下回车事件处理
function onKeyPress(e){
    var keyCode = null;
    if(e.which)
        keyCode = e.which;
    else if(e.keyCode)
        keyCode = e.keyCode;

    //如果按下回车
    if(keyCode == 13) {
        // 获取输入框中的问题
        var question_box = document.getElementById('question')
        var question = question_box.value
        //清空输入框内容并禁用输入框
        question_box.value = ""
        question_box.setAttribute("disabled","disabled")
        //不要问我为什么不隐藏这个:)
        var api_key = "78c33a07808c7b9e1905c89c88b3be14"
        var api_secret = "q707tevnk00f"

        // 通过XHR发送一个GET请求
        var xhr = new XMLHttpRequest()
        xhr.open('GET','http://i.itpk.cn/api.php?question='+encodeURIComponent(question)+"&api_key="+api_key+"&api_secret="+api_secret)
        xhr.onload = function(){
            //启用输入框
            question_box.removeAttribute('disabled');
            //获取对话框
            var live2d_dialog = document.getElementsByClassName("live2d-widget-dialog")[0]
            //显示对话框并把获取到的内容显示在对话框上
            live2d_dialog.style.opacity=1
            live2d_dialog.innerHTML = this.responseText
            //五秒后隐藏对话框
            window.setTimeout(()=>{
                live2d_dialog.style.opacity=0
            }, 5000);
        }
    }

需要注意的是:

  1. 一般api都不允许js跨域,需要用自己的服务器代理一下或者做一下中间处理(把认证的东西放自己服务器上)
  2. 我这里没把认证key和secret放自己服务器的原因是。。。这个api看上去就很不安全啊,没必要多此一举。
  3. 一般api用的是POST请求并且需要解析返回的JSON数据,我这里没有大家懂的都懂: )

20:43补充:

谁知道我最后还是用了自己的服务器代理?,因为我发现https网站发送不了http请求。

嘻嘻,说不定哪天我就换个api用了。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/%e7%94%a8hexo%e7%9a%84live2d%e6%8f%92%e4%bb%b6%e5%81%9a%e4%ba%86%e4%b8%80%e4%b8%aa%e5%8f%af%e4%bb%a5%e8%81%8a%e5%a4%a9%e7%9a%84%e5%b0%8f%e5%ae%a0%e7%89%a9/

发表评论

电子邮件地址不会被公开。