今天觉得我的博客有点小小的简陋,就做了一点美化工作
主要使用hexo的live2d插件(感谢作者),搭配上机器人对话api,做了一个可以聊天的小宠物。
本来是在live2d的github主页上看到了有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);
}
}
需要注意的是:
- 一般api都不允许js跨域,需要用自己的服务器代理一下或者做一下中间处理(把认证的东西放自己服务器上)
- 我这里没把认证key和secret放自己服务器的原因是。。。这个api看上去就很不安全啊,没必要多此一举。
- 一般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/