FGHRSH 的博客

Please wait...

网页添加 Live2D 看板娘

没错我也加上了,好萌啊  ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ 

最近无意中又看到了 @Jad 大佬的博客,不拖坑了,加加加 233


在 dalao 的 waifu-tips.js 的基础上,实现了套 API,加上了以下功能


  • 可以切换 Live2D 模型了(暂时只有 Pio 和 Tia 酱

  • 支持 随机换装 和 顺序换装(收集了截至目前的 Pio、Tia 全套服装


以下内容需要根据 自身情况 进行修改,不能直接套用


样式

.waifu {
    position: fixed;
    bottom: 0;
    left: 0;
    z-index: 1;
    font-size: 0;
    transition: all .3s ease-in-out;
    -webkit-transform: translateY(3px);
    transform: translateY(3px);
}
.waifu:hover {
    -webkit-transform: translateY(0);
    transform: translateY(0);
}
@media (max-width: 768px) {
    .waifu {
        display: none;
    }
}
.waifu-tips {
    opacity: 0;
    width: 250px;
    height: 70px;
    margin: -20px 20px;
    padding: 5px 10px;
    border: 1px solid rgba(224, 186, 140, 0.62);
    border-radius: 12px;
    background-color: rgba(236, 217, 188, 0.5);
    box-shadow: 0 3px 15px 2px rgba(191, 158, 118, 0.2);
    font-size: 12px;
    text-overflow: ellipsis;
    overflow: hidden;
    position: absolute;
    animation-delay: 5s;
    animation-duration: 50s;
    animation-iteration-count: infinite;
    animation-name: shake;
    animation-timing-function: ease-in-out;
}
.waifu-tool {
    display: none;
    color: #aaa;
    top: 50px;
    right: 10px;
    font-size: 14px;
    position: absolute;
}
.waifu:hover .waifu-tool {
    display: block;
}
.waifu-tool span {
    display: block;
    cursor: pointer;
    color: #5b6c7d;
    line-height: 20px;
    transition: 0.2s;
}
.waifu-tool span:hover {
    color: #34495e;
}
.waifu #live2d{
    position: relative;
}

@keyframes shake {
    2% {
        transform: translate(0.5px, -1.5px) rotate(-0.5deg);
    }

    4% {
        transform: translate(0.5px, 1.5px) rotate(1.5deg);
    }

    6% {
        transform: translate(1.5px, 1.5px) rotate(1.5deg);
    }

    8% {
        transform: translate(2.5px, 1.5px) rotate(0.5deg);
    }

    10% {
        transform: translate(0.5px, 2.5px) rotate(0.5deg);
    }

    12% {
        transform: translate(1.5px, 1.5px) rotate(0.5deg);
    }

    14% {
        transform: translate(0.5px, 0.5px) rotate(0.5deg);
    }

    16% {
        transform: translate(-1.5px, -0.5px) rotate(1.5deg);
    }

    18% {
        transform: translate(0.5px, 0.5px) rotate(1.5deg);
    }

    20% {
        transform: translate(2.5px, 2.5px) rotate(1.5deg);
    }

    22% {
        transform: translate(0.5px, -1.5px) rotate(1.5deg);
    }

    24% {
        transform: translate(-1.5px, 1.5px) rotate(-0.5deg);
    }

    26% {
        transform: translate(1.5px, 0.5px) rotate(1.5deg);
    }

    28% {
        transform: translate(-0.5px, -0.5px) rotate(-0.5deg);
    }

    30% {
        transform: translate(1.5px, -0.5px) rotate(-0.5deg);
    }

    32% {
        transform: translate(2.5px, -1.5px) rotate(1.5deg);
    }

    34% {
        transform: translate(2.5px, 2.5px) rotate(-0.5deg);
    }

    36% {
        transform: translate(0.5px, -1.5px) rotate(0.5deg);
    }

    38% {
        transform: translate(2.5px, -0.5px) rotate(-0.5deg);
    }

    40% {
        transform: translate(-0.5px, 2.5px) rotate(0.5deg);
    }

    42% {
        transform: translate(-1.5px, 2.5px) rotate(0.5deg);
    }

    44% {
        transform: translate(-1.5px, 1.5px) rotate(0.5deg);
    }

    46% {
        transform: translate(1.5px, -0.5px) rotate(-0.5deg);
    }

    48% {
        transform: translate(2.5px, -0.5px) rotate(0.5deg);
    }

    50% {
        transform: translate(-1.5px, 1.5px) rotate(0.5deg);
    }

    52% {
        transform: translate(-0.5px, 1.5px) rotate(0.5deg);
    }

    54% {
        transform: translate(-1.5px, 1.5px) rotate(0.5deg);
    }

    56% {
        transform: translate(0.5px, 2.5px) rotate(1.5deg);
    }

    58% {
        transform: translate(2.5px, 2.5px) rotate(0.5deg);
    }

    60% {
        transform: translate(2.5px, -1.5px) rotate(1.5deg);
    }

    62% {
        transform: translate(-1.5px, 0.5px) rotate(1.5deg);
    }

    64% {
        transform: translate(-1.5px, 1.5px) rotate(1.5deg);
    }

    66% {
        transform: translate(0.5px, 2.5px) rotate(1.5deg);
    }

    68% {
        transform: translate(2.5px, -1.5px) rotate(1.5deg);
    }

    70% {
        transform: translate(2.5px, 2.5px) rotate(0.5deg);
    }

    72% {
        transform: translate(-0.5px, -1.5px) rotate(1.5deg);
    }

    74% {
        transform: translate(-1.5px, 2.5px) rotate(1.5deg);
    }

    76% {
        transform: translate(-1.5px, 2.5px) rotate(1.5deg);
    }

    78% {
        transform: translate(-1.5px, 2.5px) rotate(0.5deg);
    }

    80% {
        transform: translate(-1.5px, 0.5px) rotate(-0.5deg);
    }

    82% {
        transform: translate(-1.5px, 0.5px) rotate(-0.5deg);
    }

    84% {
        transform: translate(-0.5px, 0.5px) rotate(1.5deg);
    }

    86% {
        transform: translate(2.5px, 1.5px) rotate(0.5deg);
    }

    88% {
        transform: translate(-1.5px, 0.5px) rotate(1.5deg);
    }

    90% {
        transform: translate(-1.5px, -0.5px) rotate(-0.5deg);
    }

    92% {
        transform: translate(-1.5px, -1.5px) rotate(1.5deg);
    }

    94% {
        transform: translate(0.5px, 0.5px) rotate(-0.5deg);
    }

    96% {
        transform: translate(2.5px, -0.5px) rotate(-0.5deg);
    }

    98% {
        transform: translate(-1.5px, -1.5px) rotate(-0.5deg);
    }

    0%, 100% {
        transform: translate(0, 0) rotate(0);
    }
}
@font-face {
  font-family: 'Flat-UI-Icons';
  src: url('flat-ui-icons-regular.eot');
  src: url('flat-ui-icons-regular.eot?#iefix') format('embedded-opentype'), url('flat-ui-icons-regular.woff') format('woff'), url('flat-ui-icons-regular.ttf') format('truetype'), url('flat-ui-icons-regular.svg#flat-ui-icons-regular') format('svg');
}
[class^="fui-"],
[class*="fui-"] {
  font-family: 'Flat-UI-Icons';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.fui-cross:before {
  content: "\e609";
}
.fui-info-circle:before {
  content: "\e60f";
}
.fui-photo:before {
  content: "\e62a";
}
.fui-eye:before {
  content: "\e62c";
}
.fui-chat:before {
  content: "\e62d";
}
.fui-home:before {
  content: "\e62e";
}
.fui-user:before {
  content: "\e631";
}


waifu-tips.js

String.prototype.render = function (context) {
    var tokenReg = /(\\)?\{([^\{\}\\]+)(\\)?\}/g;

    return this.replace(tokenReg, function (word, slash1, token, slash2) {
        if (slash1 || slash2) {  
            return word.replace('\\', '');
        }

        var variables = token.replace(/\s/g, '').split('.');
        var currentObject = context;
        var i, length, variable;

        for (i = 0, length = variables.length; i < length; ++i) {
            variable = variables[i];
            currentObject = currentObject[variable];
            if (currentObject === undefined || currentObject === null) return '';
        }
        return currentObject;
    });
};

var re = /x/;
console.log(re);
re.toString = function() {
    showMessage('哈哈,你打开了控制台,是想要看看我的秘密吗?', 5000, true);
    return '';
};

$(document).on('copy', function (){
    showMessage('你都复制了些什么呀,转载要记得加上出处哦', 5000, true);
});

$('.waifu-tool .fui-home').click(function (){
    //window.location = 'https://www.fghrsh.net/';
    window.location = window.location.protocol+'//'+window.location.hostname+'/'
});

$('.waifu-tool .fui-eye').click(function (){
    loadOtherModel();
});

$('.waifu-tool .fui-chat').click(function (){
    showHitokoto();
});

$('.waifu-tool .fui-user').click(function (){
    loadRandModel();
});

$('.waifu-tool .fui-info-circle').click(function (){
    //window.open('https://imjad.cn/archives/lab/add-dynamic-poster-girl-with-live2d-to-your-blog-02');
    window.open('https://www.fghrsh.net/post/123.html');
});

$('.waifu-tool .fui-cross').click(function (){
    sessionStorage.setItem('waifu-dsiplay', 'none');
    showMessage('愿你有一天能与重要的人重逢', 1300, true);
    window.setTimeout(function() {$('.waifu').hide();}, 1300);
});

$('.waifu-tool .fui-photo').click(function (){
    showMessage('照好了嘛,是不是很可爱呢?', 5000, true);
    window.Live2D.captureName = 'live2d.png';
    window.Live2D.captureFrame = true;
});

(function (){
    var text;
    //var SiteIndexUrl = 'https://www.fghrsh.net/';  // 手动指定主页
    var SiteIndexUrl = window.location.protocol+'//'+window.location.hostname+'/';  // 自动获取主页
    
    if (window.location.href == SiteIndexUrl) {      // 如果是主页
        var now = (new Date()).getHours();
        if (now > 23 || now <= 5) {
            text = '你是夜猫子呀?这么晚还不睡觉,明天起的来嘛';
        } else if (now > 5 && now <= 7) {
            text = '早上好!一日之计在于晨,美好的一天就要开始了';
        } else if (now > 7 && now <= 11) {
            text = '上午好!工作顺利嘛,不要久坐,多起来走动走动哦!';
        } else if (now > 11 && now <= 14) {
            text = '中午了,工作了一个上午,现在是午餐时间!';
        } else if (now > 14 && now <= 17) {
            text = '午后很容易犯困呢,今天的运动目标完成了吗?';
        } else if (now > 17 && now <= 19) {
            text = '傍晚了!窗外夕阳的景色很美丽呢,最美不过夕阳红~';
        } else if (now > 19 && now <= 21) {
            text = '晚上好,今天过得怎么样?';
        } else if (now > 21 && now <= 23) {
            text = '已经这么晚了呀,早点休息吧,晚安~';
        } else {
            text = '嗨~ 快来逗我玩吧!';
        }
    } else {
        if(document.referrer !== ''){
            var referrer = document.createElement('a');
            referrer.href = document.referrer;
            var domain = referrer.hostname.split('.')[1];
            if (window.location.hostname == referrer.hostname) {
                text = '欢迎阅读<span style="color:#0099cc;">『' + document.title.split(' - ')[0] + '』</span>';
            } else if (domain == 'baidu') {
                text = 'Hello! 来自 百度搜索 的朋友<br>你是搜索 <span style="color:#0099cc;">' + referrer.search.split('&wd=')[1].split('&')[0] + '</span> 找到的我吗?';
            } else if (domain == 'so') {
                text = 'Hello! 来自 360搜索 的朋友<br>你是搜索 <span style="color:#0099cc;">' + referrer.search.split('&q=')[1].split('&')[0] + '</span> 找到的我吗?';
            } else if (domain == 'google') {
                text = 'Hello! 来自 谷歌搜索 的朋友<br>欢迎阅读<span style="color:#0099cc;">『' + document.title.split(' - ')[0] + '』</span>';
            } else {
                text = 'Hello! 来自 <span style="color:#0099cc;">' + referrer.hostname + '</span> 的朋友';
            }
        } else {
            text = '欢迎阅读<span style="color:#0099cc;">『' + document.title.split(' - ')[0] + '』</span>';
        }
    }
    showMessage(text, 6000);
})();

//window.hitokotoTimer = window.setInterval(showHitokoto,30000);
/* 检测用户活动状态,并在空闲时 定时显示一言 */
var getActed = false;
window.hitokotoTimer = 0;
var hitokotoInterval = false;

$(document).mousemove(function(e){getActed = true;}).keydown(function(){getActed = true;});
setInterval(function() { if (!getActed) ifActed(); else elseActed(); }, 1000);

function ifActed() {
    if (!hitokotoInterval) {
        hitokotoInterval = true;
        hitokotoTimer = window.setInterval(showHitokoto, 30000);
    }
}

function elseActed() {
    getActed = hitokotoInterval = false;
    window.clearInterval(hitokotoTimer);
}

function showHitokoto(){
    $.getJSON('//api.fghrsh.net/hitokoto/rand/?encode=jsc&uid=3335',function(result){
        var text = '这句一言出处是 <span style="color:#0099cc;">『{source}』</span>,是 <span style="color:#0099cc;">FGHRSH</span> 在 {date} 收藏的!';
        text = text.render({source: result.source, date: result.date});
        showMessage(result.hitokoto, 5000);
        window.setTimeout(function() {showMessage(text, 3000);}, 5000);
    });
}

function showMessage(text, timeout, flag){
    if(flag || sessionStorage.getItem('waifu-text') === '' || sessionStorage.getItem('waifu-text') === null){
        if(Array.isArray(text)) text = text[Math.floor(Math.random() * text.length + 1)-1];
        //console.log(text);
        
        if(flag) sessionStorage.setItem('waifu-text', text);
        
        $('.waifu-tips').stop();
        $('.waifu-tips').html(text).fadeTo(200, 1);
        hideMessage(timeout);
    }
}

function hideMessage(timeout=5000){
    $('.waifu-tips').stop().css('opacity',1);
    $('.waifu-tips').delay(timeout).fadeTo(200, 0);
    window.setTimeout(function() {sessionStorage.removeItem('waifu-text');}, timeout);
}

function initModel(waifuPath=''){
    
    var modelId = localStorage.getItem('modelId');
    var modelTexturesId = localStorage.getItem('modelTexturesId');
    
    if (modelId == null) {
        
        /* 首次访问加载 指定模型 的 指定材质 */
        
        var modelId = 1;            // 模型 ID
        var modelTexturesId = 53    // 材质 ID
        
    } loadModel(modelId, modelTexturesId);
	
	$.ajax({
        cache: true,
        url: waifuPath+'waifu-tips.json',
        dataType: "json",
        success: function (result){
            $.each(result.mouseover, function (index, tips){
                $(document).on("mouseover", tips.selector, function (){
                    var text = tips.text;
                    if(Array.isArray(tips.text)) text = tips.text[Math.floor(Math.random() * tips.text.length + 1)-1];
                    text = text.render({text: $(this).text()});
                    showMessage(text, 3000);
                });
            });
            $.each(result.click, function (index, tips){
                $(document).on("click", tips.selector, function (){
                    var text = tips.text;
                    if(Array.isArray(tips.text)) text = tips.text[Math.floor(Math.random() * tips.text.length + 1)-1];
                    text = text.render({text: $(this).text()});
                    showMessage(text, 3000, true);
                });
            });
            $.each(result.seasons, function (index, tips){
                var now = new Date();
                var after = tips.date.split('-')[0];
                var before = tips.date.split('-')[1] || after;
                
                if((after.split('/')[0] <= now.getMonth()+1 && now.getMonth()+1 <= before.split('/')[0]) && 
                   (after.split('/')[1] <= now.getDate() && now.getDate() <= before.split('/')[1])){
                    var text = tips.text;
                    if(Array.isArray(tips.text)) text = tips.text[Math.floor(Math.random() * tips.text.length + 1)-1];
                    text = text.render({year: now.getFullYear()});
                    showMessage(text, 6000, true);
                }
            });
        }
    });
}

function loadModel(modelId, modelTexturesId=0){
    localStorage.setItem('modelId', modelId);
    localStorage.setItem('modelTexturesId', modelTexturesId);
    loadlive2d('live2d', '//api.fghrsh.net/live2d/get/?id='+modelId+'-'+modelTexturesId, console.log('live2d','模型 '+modelId+'-'+modelTexturesId+' 加载完成'));
}

function loadRandModel(){
    var modelId = localStorage.getItem('modelId');
    var modelTexturesId = localStorage.getItem('modelTexturesId');
    
    var modelTexturesRandMode = 'rand';     // 可选 'rand'(随机), 'switch'(顺序)
    
    $.ajax({
        cache: false,
        url: '//api.fghrsh.net/live2d/'+modelTexturesRandMode+'_textures/?id='+modelId+'-'+modelTexturesId,
        dataType: "json",
        success: function (result){
            if (result.textures['id'] == 1 && (modelTexturesId == 1 || modelTexturesId == 0)) {
                showMessage('我还没有其他衣服呢', 3000, true);
            } else {
                showMessage('我的新衣服好看嘛', 3000, true);
            }
            loadModel(modelId, result.textures['id']);
        }
    });
}

function loadOtherModel(){
    var modelId = localStorage.getItem('modelId');
    
    var modelTexturesRandMode = 'switch';     // 可选 'rand'(随机), 'switch'(顺序)
    
    $.ajax({
        cache: false,
        url: '//api.fghrsh.net/live2d/'+modelTexturesRandMode+'/?id='+modelId,
        dataType: "json",
        success: function (result){
            loadModel(result.model['id']);
            showMessage(result.model['message'], 3000, true);
        }
    });
}


waifu-tips.json

{
    "mouseover": [
        {
            "selector": ".container a[href^='http']",
            "text": ["要看看 <span style=\"color:#0099cc;\">{text}</span> 么?"]
        },
        {
            "selector": ".fui-home",
            "text": ["点击前往首页,想回到上一页可以使用浏览器的后退功能哦"]
        },
        {
            "selector": "#tor_show",
            "text": ["翻页比较麻烦吗,点击可以显示这篇文章的目录呢"]
        },
        {
            "selector": "#comment_go,.fui-chat",
            "text": ["想要去评论些什么吗?"]
        },
        {
            "selector": "#night_mode",
            "text": ["深夜时要爱护眼睛呀"]
        },
        {
            "selector": "#qrcode",
            "text": ["手机扫一下就能继续看,很方便呢"]
        },
        {
            "selector": ".comment_reply",
            "text": ["要吐槽些什么呢"]
        },
        {
            "selector": "#back-to-top",
            "text": ["回到开始的地方吧"]
        },
        {
            "selector": "#author",
            "text": ["该怎么称呼你呢"]
        },
        {
            "selector": "#mail",
            "text": ["留下你的邮箱,不然就是无头像人士了"]
        },
        {
            "selector": "#url",
            "text": ["你的家在哪里呢,好让我去参观参观"]
        },
        {
            "selector": "#textarea",
            "text": ["认真填写哦,垃圾评论是禁止事项"]
        },
        {
            "selector": ".OwO-logo",
            "text": ["要插入一个表情吗"]
        },
        {
            "selector": "#csubmit",
            "text": ["要[提交]^(Commit)了吗,首次评论需要审核,请耐心等待~"]
        },
        {
            "selector": ".ImageBox",
            "text": ["点击图片可以放大呢"]
        },
        {
            "selector": "input[name=s]",
            "text": ["找不到想看的内容?搜索看看吧"]
        },
        {
            "selector": ".previous",
            "text": ["去上一页看看吧"]
        },
        {
            "selector": ".next",
            "text": ["去下一页看看吧"]
        },
        {
            "selector": ".dropdown-toggle",
            "text": ["这里是菜单"]
        },
        {
            "selector": "c-player a.play-icon",
            "text": ["想要听点音乐吗"]
        },
        {
            "selector": "c-player div.time",
            "text": ["在这里可以调整<span style=\"color:#0099cc;\">播放进度</span>呢"]
        },
        {
            "selector": "c-player div.volume",
            "text": ["在这里可以调整<span style=\"color:#0099cc;\">音量</span>呢"]
        },
        {
            "selector": "c-player div.list-button",
            "text": ["<span style=\"color:#0099cc;\">播放列表</span>里都有什么呢"]
        },
        {
            "selector": "c-player div.lyric-button",
            "text": ["有<span style=\"color:#0099cc;\">歌词</span>的话就能跟着一起唱呢"]
        },
        {
            "selector": ".waifu #live2d",
            "text": ["干嘛呢你,快把手拿开", "鼠…鼠标放错地方了!"]
        }
    ],
     "click": [
        {
            "selector": ".waifu #live2d",
            "text": ["是…是不小心碰到了吧", "萝莉控是什么呀", "你看到我的小熊了吗", "再摸的话我可要报警了!⌇●﹏●⌇", "110吗,这里有个变态一直在摸我(ó﹏ò。)"]
        }
    ],
    "seasons": [
        {
            "date": "01/01",
            "text": "<span style=\"color:#0099cc;\">元旦</span>了呢,新的一年又开始了,今年是{year}年~"
        },
        {
            "date": "02/14",
            "text": "又是一年<span style=\"color:#0099cc;\">情人节</span>,{year}年找到对象了嘛~"
        },
        {
            "date": "03/08",
            "text": "今天是<span style=\"color:#0099cc;\">妇女节</span>!"
        },
        {
            "date": "03/12",
            "text": "今天是<span style=\"color:#0099cc;\">植树节</span>,要保护环境呀"
        },
        {
            "date": "04/01",
            "text": "悄悄告诉你一个秘密~<span style=\"background-color:#34495e;\">今天是愚人节,不要被骗了哦~</span>"
        },
        {
            "date": "05/01",
            "text": "今天是<span style=\"color:#0099cc;\">五一劳动节</span>,计划好假期去哪里了吗~"
        },
        {
            "date": "06/01",
            "text": "<span style=\"color:#0099cc;\">儿童节</span>了呢,快活的时光总是短暂,要是永远长不大该多好啊…"
        },
        {
            "date": "09/03",
            "text": "<span style=\"color:#0099cc;\">中国人民抗日战争胜利纪念日</span>,铭记历史、缅怀先烈、珍爱和平、开创未来。"
        },
        {
            "date": "09/10",
            "text": "<span style=\"color:#0099cc;\">教师节</span>,在学校要给老师问声好呀~"
        },
        {
            "date": "10/01",
            "text": "<span style=\"color:#0099cc;\">国庆节</span>,新中国已经成立69年了呢"
        },
        {
            "date": "11/05-11/12",
            "text": "今年的<span style=\"color:#0099cc;\">双十一</span>是和谁一起过的呢~"
        },
        {
            "date": "12/20-12/31",
            "text": "这几天是<span style=\"color:#0099cc;\">圣诞节</span>,主人肯定又去剁手买买买了~"
        }
    ]
}


加进 header.php

<!-- 加载样式 -->
<link rel="stylesheet" type="text/css" href="https://www.example.com/path/to/waifu.css"/>


加进 footer.php(须 jQuery 支持)

<div class="waifu">
    
    <!-- 提示框 -->
    <div class="waifu-tips"></div>
    
    <!-- 看板娘画布 -->
    <canvas id="live2d" width="280" height="250" class="live2d"></canvas>
    
    <!-- 工具栏 -->
    <div class="waifu-tool">
        <span class="fui-home"></span>
        <span class="fui-chat"></span>
        <span class="fui-eye"></span>
        <span class="fui-user"></span>
        <span class="fui-photo"></span>
        <span class="fui-info-circle"></span>
        <span class="fui-cross"></span>
    </div>
    
</div>

<script src="path/to/waifu-tips.js"></script>
<script src="path/to/live2d.js"></script>

<!-- 初始化看板娘,会自动加载指定目录下的 waifu-tips.json -->
<script type="text/javascript">initModel("https://www.example.com/path/to/")</script>


或 实现自动加载,在 footer.php 的最后加上

<script src="https://www.example.com/path/to/autoload.js" type="text/javascript"></script>


autoload.js

// 加载 CSS
$("<link>").attr({href: "https://www.example.com/path/to/waifu.css", rel: "stylesheet", type: "text/css"}).appendTo('head');

// 插入 DIV
$('body').append('<div class="waifu"><div class="waifu-tips"></div><canvas id="live2d" width="280" height="250" class="live2d"></canvas><div class="waifu-tool"><span class="fui-home"></span> <span class="fui-chat"></span> <span class="fui-eye"></span> <span class="fui-user"></span> <span class="fui-photo"></span> <span class="fui-info-circle"></span> <span class="fui-cross"></span></div></div>');

// 加载 JS
$.ajax({
	url: 'https://www.example.com/path/to/live2d.js',
	dataType:"script",
	cache: true,
	async: false
});
$.ajax({
	url: 'https://www.example.com/path/to/waifu-tips.js',
	dataType:"script",
	cache: true,
	async: false
});

// 初始化看板娘,会自动加载指定目录下的 waifu-tips.json
initModel('https://www.example.com/path/to/');


打包下载


API 接口

  • 截至目前,接口每日请求数高达 60+万次,并产生了大量的流量... 

  • 在 2018.05.12~2018.06.10 期间,API 请求数已达到 20138636 次

  • 希望大站 dalao 们看到能自建 API,源码在上方(可以联系我协助搭建


更新日志

  • 2018-01-03:live2d.js 修复 IE,Edge 兼容性问题

  • 2018-03-02:API 新增 22,33,Shizuku,Neptunia 系列,Murakumo 模型

  • 2018-05-20:修复 waifu-tips.json 导致的 小bug,增加使用 hitokoto.cn 一言 API


其他插件

Tips: 以上插件大概能替换 waifu-tips.js 来使用这边的 API (逃


参考资料




版权信息


本文标题:网页添加 Live2D 看板娘
本文链接:https://www.fghrsh.net/post/123.html
作者授权:除特别说明外,本文由 fghrsh 原创编译并授权 FGHRSH 的博客 刊载发布。
版权声明:本文使用「署名-非商业性使用-相同方式共享 4.0 国际」创作共享协议,转载或使用请遵守署名协议。

网友评论121

  1. deng 2018-09-23 22:51:34 回复

    Console 请求的资源上没有“访问-控制-允许-原点”头。
    因此,不允许访问原语“NULL”。这个怎么搞 = = 用的是phpstudy

    1. fghrsh 2018-09-24 23:00:30 回复

      Access-Control-Allow-Origin ?
      apache 在虚拟主机配置文件中加上 Header set Access-Control-Allow-Origin *

      1. deng 2018-09-25 09:45:18 回复

        感谢(๑•ᴗ•๑)

  1. deng 2018-09-23 10:47:01 回复

    怎么自建 API...网上找的hph服务什么的把文件拉进去修改 waifu-tips.js的链接还是不行(눈_눈)

  1. Windsor 2018-09-22 07:17:44 回复

    大佬qwq,请问live2D如何使用本地的模型和皮肤?在哪里可以设置,难道这个就只能联网加载了么

    1. fghrsh 2018-09-24 22:56:39 回复

      这个只能联网加载.. (可以内网搭建,API 需要 PHP 环境

  1. LS_cak 2018-09-10 21:24:42 回复

    dalao您Livd2D能够拖动的效果是怎么实现的呢?

    1. fghrsh 2018-09-12 23:39:04 回复

      这边是用 jQuery UI 的 Draggable 实现的,参考:http://www.runoob.com/jqueryui/example-draggable.html

  1. Shaka 2018-09-07 15:07:45 回复

    大佬,可以先用你的API吗,后面在自己建一个...

    1. fghrsh 2018-09-08 15:31:08 回复

      可以的,日后停止服务或变更的话会在本面页更新

  1. 余余 2018-08-29 15:40:48 回复

    live2d.js:1 Uncaught TypeError: Cannot read property 'addEventListener' of null
    at o (live2d.js:1)
    at L (live2d.js:1)
    at loadModel (waifu-tips.js:233)
    at initModel (waifu-tips.js:189)
    at about:143
    o @ live2d.js:1
    L @ live2d.js:1
    loadModel @ waifu-tips.js:233
    initModel @ waifu-tips.js:189
    (anonymous) @ about:143
    为什么我总会报这个错误呢,用的你线上api偶尔会偶尔不会,我下了api部到自己服务器就一定会这样了,人物显示不出来,也没看到跨域问题的报错,我nginx上有处理跨域

    1. 余余 2018-08-29 16:15:40 回复

      自己解决了采用自动加载的方式就可以了,可能因为的那个博客框架的问题导致元素没有正常完成加载

  1. 上弦之月 2018-08-25 18:47:33 回复

    可以自建API挺好的唉 喜欢这个版本的网页live2d就是因为这个

  1. itkone 2018-08-15 15:06:11 回复

    大佬 我如果要在cocos2d里面实现这种 跟随手指移动的转动,要怎么做呢~

    1. fghrsh 2018-08-18 21:34:22 回复

      啊.. 没用过 cocos2d

  1. lord 2018-08-10 09:31:59 回复

    要是有大佬把这个改成伪春菜那该多好啊

    1. fghrsh 2018-08-11 06:05:26 回复

      _(:3 」∠ )_ Todo List +1

  1. Garen 2018-07-29 12:10:05 回复

    我给了个二级域名,丢在了服务器上,怎么解决跨域问题吖。。

    1. Garen 2018-07-29 12:13:40 回复

      已解决 ,在配置文件加入
      add_header 'Access-Control-Allow-Origin' "*";
      add_header 'Access-Control-Allow-Credentials' "true";

  1. G爱人 2018-07-29 09:34:27 回复

    大佬想加你好友,还想和你一起玩steam 你貌似没同意

    1. fghrsh 2018-07-29 21:52:48 回复

      (*/ω\*) 同意了,最近坑太多...

  1. NeyaCat 2018-07-28 17:45:16 回复

    话说……老哥,怎么解决跨域的问题?

    1. NeyaCat 2018-07-28 17:49:26 回复

      我将git的api部署到了我的服务器上,然后用一个二级域名不一样的项目请求它,遇到跨域问题。。。给get/index.php加上header之后
      XMLHttpRequest cannot load http://xxxxx/api/model/Potion-Maker/Tia/model.moc. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http:/yyyyy.com' is therefore not allowed access.
      这样,就很难受。我看你那个就没有跨域问题,hummmm

  1. 寒夏Sama 2018-07-25 08:48:02 回复

    大佬你好,似乎模型6-3贴图损坏了,能麻烦看一下吗?

    1. fghrsh 2018-07-26 22:35:59 回复

      这边能加载出来,不过 海王星 系列的贴图比较大,第一次加载可能时间会比较长...

  1. 惶心 2018-07-24 01:12:56 回复

    那啥……大佬……这个插件有打算更新啥的吗……还是写死一个以后就不更新了。如果有打算继续更新的话能否丢个 GitHub?最近再做一个项目想把您的插件适配进去(https://get.js.org/zblog-plugin-live2d),如果通过 GitHub 更新的话我可以很方便地通过 GitHub API 为用户提供最新版本

    1. fghrsh 2018-07-24 18:42:57 回复

      (*/ω\*) 有打算更新的,不过原项目是 GPL v2 (live2d.js),我还没了解清楚直接打包 js 来用是不是也要以 GPL v2 协议开源

      1. 惶心 2018-07-25 00:19:25 回复

        据我的了解……貌似是的。如果不打算以 GitHub 更新,可否邀请您成为 HXCO Get 的 贡献者,为自己的项目更新最新下载链接?

        1. fghrsh 2018-07-26 22:39:48 回复

          现在在填别的坑.. 下次更新我发上 GitHub 吧... (咕咕咕(药丸
          顺带一提,那个压缩包是纯 HTML 的 demo .. 可以自行适配任何前端,不是 z-blog 的( .zba 那个才是

  1. Beats 2018-07-16 10:46:20 回复

    大佬,要怎样搭建自己的API呢?

    1. fghrsh 2018-07-16 17:02:22 回复

      Github 下载一份到你网站就行了,然后全局替换所有的 //api.fghrsh.net/live2d/ 成你的 API 地址

      1. Hikigaya 2018-09-24 15:56:43 回复

        做成了个桌面挂件,感谢分享!

  1. Hamakaze 2018-07-13 11:07:55 回复

    dalao能加一下我的qq吗,发了申请没有回复诶。想问一下关于live2d的问题

    1. fghrsh 2018-07-15 23:27:07 回复

      最近的申请应该是全部同意了的啊.. 你再申请下试试?

  1. Mimi 2018-07-11 00:59:56 回复

    这里有不少模型,改文件名,调整渲染尺寸后可以用 https://github.com/xiazeyu/live2d-widget-models/tree/master/packages
    ## 有猫咪,没有猫娘
    ## 捂脸 逃

    1. EDEN 2018-08-04 20:42:17 回复

      老哥老哥,你知道这个模型怎么导入显示吗 用不来。。

    1. fghrsh 2018-07-15 23:27:47 回复

      (๑•̀ㅂ•́)و✧ 下次更新加上

  1. 雪散 2018-06-30 20:34:26 回复

    我发现了有个问题,每次live2d做自动小动作的时候,都要发个请求,请求动作的mtn文件,虽然会缓存,但是每次都要发送请求校对,差不多每自动做次小动作,消耗0.01kb的流量,有什么好的解决方案吗?

    1. Mimi 2018-07-14 17:36:14 回复

      请求是live2d.js中的唯一一个new XMLHttpRequest发出的,服务器端设置Expires和Cache-Control的http头,可以要求浏览器默认使用缓存的内容,而不发出请求

    1. fghrsh 2018-07-07 19:11:56 回复

      这个暂时无解,大概要从 live2d.js 动手了

  1. 雪散 2018-06-29 09:50:21 回复

    live2d模型都是从哪里弄来的啊?我怎么一个也找不到的说,想要舰C赤城模型的说

    1. fghrsh 2018-07-07 19:08:52 回复

      百度...

  1. 小猫匠 2018-06-25 21:56:29 回复

    wow不知道有没有猫的形象...

    1. fghrsh 2018-06-29 02:52:48 回复

      _(:3」∠)_ 已加入 Todo List (还没找到好看的模型,有喜欢的 Live2D 模型也可以打包发到我邮箱

  1. 2018-06-19 16:02:20 回复

    一直请求的动作文件 会影响服务器性能吗

    1. fghrsh 2018-06-19 16:07:57 回复

      你可以 F12 到 Network 看看,一般动作文件都有缓存,from cache 就是请求了本地的缓存文件而已

  1. heroyf 2018-06-10 09:25:48 回复

    大佬,你的api今天好像是不是炸惹,显示不出东西了ヾ(o・ω・)ノ

    1. fghrsh 2018-06-11 00:17:46 回复

      (。˃﹏˂) 已恢复

  1. zhaibo01 2018-06-06 10:43:13 回复

    Z-Blog PHP 插件不能下载吗?

    1. fghrsh 2018-06-06 15:34:38 回复

      已修复响应类型...(如果还是直接加载了内容的话,其实可以 右键另存为 保存文件,不影响使用的

  1. kam 2018-06-02 17:17:11 回复

    要是有猫咪的就好了

  1. 瑞王 2018-05-24 23:49:59 回复

    咋修改默认造型啊!!!!求助

    1. fghrsh 2018-05-25 23:52:00 回复

      修改 waifu-tips.js 里有 中文注释 的地方(默认模型),模型ID 和 材质ID 可以随机然后 F12 抓到,要添加的话,就要自建 API 了

      1. hahaha 2018-05-26 17:50:01 回复

        谢啦,棒棒哒

  1. pandora 2018-05-23 12:56:42 回复

    大佬你好,我在移动鼠标或点击时出现人物上方文字闪烁,变模糊情况,请问怎么解决?

  1. hurria 2018-05-23 09:00:57 回复

    谢谢大佬,,我解决了本地加载的问题。。但是大佬,没有显示模型啊,要增么加进去呢,求解

  1. Forev 2018-05-17 20:27:26 回复

    博主 谢谢你的教程哈! LIVE2D运作的很棒 但是有个问题就是控制台出现了一个
    TypeError: a is undefined jquery.js:348:3
    怎么解决呢?

    1. fghrsh 2018-05-19 22:42:12 回复

      刚刚看了看你博客是 Access-Control-Allow-Origin 请求头的问题...

      1. Forev 2018-05-20 00:30:45 回复

        我又换回了之前按你教程做的那个版本 会报错 说什么长度没有定义 能帮忙看看吗 谢谢!!!

        1. fghrsh 2018-05-20 01:04:40 回复

          已修复,重下 v1.2 压缩包 再试试?

      1. Forev 2018-05-20 00:26:16 回复

        谢谢回复,其实这个问题我在前几天已经解决了... 不知道你现在说的问题在哪里,我控制台看已经没问题了

        1. fghrsh 2018-05-20 00:28:19 回复

          嗯,这边也恢复了

  1. Ari 2018-05-17 16:56:08 回复

    支持一下

  1. 橙子 2018-05-08 19:28:38 回复

    大佬您好,你的 showHitokoto() 方法中的返回json对象的链接是怎么做的呢?

    1. fghrsh 2018-05-12 22:58:52 回复

      一言 API,可以使用 https://hitokoto.cn/ 的接口替换

      1. 橙子 2018-05-13 07:39:06 回复

        谢谢

  1. K4KK 2018-05-08 16:56:36 回复

    为什么我右边的符号是框框呢

    1. fghrsh 2018-05-12 22:57:42 回复

      加载 fui 符号字体失败的话,就会显示框框..

  1. 由依 2018-05-07 18:08:58 回复

    怎样添加到Discuz上去

  1. Kashimura 2018-05-01 00:15:57 回复

    谢谢dalao的live2d 不过萌新有个问题想问 如何让看板娘盯着div外的指针|ω・)

    1. fghrsh 2018-05-02 00:15:56 回复

      div 外?我博客这个能盯着整个窗口的...

      1. Kashimura 2018-05-11 21:36:07 回复

        找到问题惹.原来是iframe问题的锅 _(:зゝ∠)_

      1. Kashimura 2018-05-03 18:38:00 回复

        对.只是不知道怎么实现 _(:зゝ∠)_

        1. fghrsh 2018-05-06 23:29:53 回复

          默认就是整个窗口的啊... js 那边我也没加过这类代码...

  1. 雾雨霖 2018-04-22 16:28:14 回复

    fghrsh,我看了您的教程在我自己的网页中应用了live2d,可是效果不好,我希望能设置拖动,可是jq写的有问题,希望能帮忙解决一下。https://www.fograinblog.com/

    1. ArisAgeha 2018-05-12 05:38:08 回复

      ```
      function setDraggable(){
      $('.waifu').on('mousedown', function(e1) {
      $('.waifu').css('transition', 'none');
      $(document).on('mousemove', function mousemove(e) {
      let left = e.clientX - 140 + "px";
      let top = e.clientY - 125 + "px";
      $('.waifu').css({"top":top, "left":left});
      });
      });
      $('.waifu').on('mouseup', function(){
      $(document).unbind('mousemove');
      $('.waifu').css('transition', 'all .3s ease-in-out');
      });
      }
      ```

      1. ArisAgeha 2018-05-12 05:38:54 回复

        ...格式被吞了 自行缩进一下

    1. fghrsh 2018-04-23 00:32:16 回复

      (ノ˃ω˂)ノ 我这边是用 jQuery UI 的 Draggable 实现的,只需要一行,参考:http://www.runoob.com/jqueryui/example-draggable.html

  1. emmmm 2018-04-14 02:08:25 回复

    模型加载不出来呀.一片白的

    1. fghrsh 2018-04-15 01:32:35 回复

      demo?要上传到web目录才能访问,不能直接本地打开..

      1. hurria 2018-05-14 09:07:52 回复

        大佬大佬,那有没有办法让它能在离线本地显示吗

        1. fghrsh 2018-05-19 22:35:22 回复

          本地 file:// 打开可以把 waifu-tips.js 里 "//api.fghrsh.net" 全局替换成 "https://api.fghrsh.net" ,不过要离线的话,就要内网自建 API 了

  1. Misaka_Azusa 2018-04-01 10:48:49 回复

    大佬,能加个qq学习下吗,有问题想请教

    1. fghrsh 2018-04-02 00:37:04 回复

      w(゚Д゚)w 可以啊,关于页 有联系方式 ...

  1. atesup 2018-03-24 22:36:52 回复

    怎么换到右边

    1. fghrsh 2018-03-28 18:26:00 回复

      把样式表的 .waifu {left: 0;} 改成 .waifu {right: 30px;} 就到右边了

  1. 阿离 2018-03-21 03:03:58 回复

    厉害了,有认识了个大佬

  1. 小乌龟 2018-03-17 12:04:34 回复

    嘿嘿 要改哪里才能在手机端显示呢

    1. fghrsh 2018-03-18 15:07:27 回复

      去掉这段 css 就可以了
      @media (max-width: 768px) {
      .waifu {
      display: none;
      }
      }
      (宽度低于 768px 时隐藏 .waifu)

  1. 保罗 2018-03-03 12:37:23 回复

    我的插件是可以换模型的,前提是要自己上传好模型在插件里面设置一下才行

    1. EDEN 2018-08-04 20:43:18 回复

      能具体说一下吗= = 我这边想用自己的模型但是换不来。。

      1. 保罗 2018-08-04 21:33:23 回复

        你加我的群看看吧 =_= 657692292

      1. 保罗 2018-08-04 21:12:02 回复

        你要用我的插件才可以

        1. EDEN 2018-08-04 21:15:46 回复

          我的问题就是。。模型制作那边live2d给我的格式 好像都和我们前端model.json定义的格式区别有很大。。 555 请求帮助 官网的模型我也下了的,但是不是这个样子的 比如我们是.moc 他是 .moc3然后加载肯定不能兼容了。。

  1. 小西 2018-02-24 15:29:11 回复

    在vue模块化开发中怎么用,我是萌新

    1. fghrsh 2018-02-24 18:44:01 回复

      可以参考 autoload.js,引用 waifu.css,插入 div,加载 live2d.js 和 waifu-tips.js,并指定 waifu-tips.json 路径完成加载(甚至 waifu-tips.js 可以重写下

  1. 北海 2018-02-24 13:02:43 回复

    大佬 有没有typecho的彩金嘞

    1. fghrsh 2018-02-24 18:38:58 回复

      _(:3」∠)_ 其实这个插件意义也不大,毕竟还是要自行修改 waifu-tips.json,参考 demo 加到博客就可以了

  1. heroyf 2018-02-20 13:47:11 回复

    请问我修改waifu.css样式表后,如何更新样式呢?我刷新网页后调试模式里显示的还是原来的css文件

    1. fghrsh 2018-02-20 13:55:27 回复

      浏览器缓存 可以 [Ctrl] + [F5] 强制刷新,CDN 缓存 的话就要上后台刷新了

  1. jonyjay 2018-02-12 11:15:39 回复

    博主,跪求 素材包啊!!!太喜欢了

    1. fghrsh 2018-02-12 22:27:11 回复

      ヾ(˃▽˂)〃 毕竟这是扒下来的,版权限制不太方便分享呢(嘛,可以加我 QQ 交流下

  1. 雲流匀 2018-02-10 01:06:00 回复

    看不懂怎么办

    1. fghrsh 2018-02-10 19:30:47 回复

      ...... 这个要点前端基础呢,可以下载压缩包试试 DEMO,然后跟着示例插到自己的网站上

      1. 雲流匀 2018-02-12 21:49:32 回复

        不会...我还是躺着吧

  1. 白白 2018-01-31 12:39:14 回复

    加载模型的时候,报了这个错误,是什么原因啊?
    Failed to load image : https://api3.fghrsh.net/live2d/model/Potion-Maker/Pio/textures/winter-coat-2017-costume-brown.png
    这个网址报错了

    1. fghrsh 2018-01-31 13:16:17 回复

      (˃▽˂) 刚刚在调试 API 接口,现在应该没问题了

      1. 白白 2018-01-31 13:18:36 回复

        好哒~谢谢博主!没问题了

  1. heroyf 2018-01-27 19:18:18 回复

    博主,知道为啥有时刷新后,会隐身吗,求解~

    1. fghrsh 2018-01-31 13:17:28 回复

      现在应该修复了,再试试?

      1. 梁Sir 2018-01-31 13:20:42 回复

        多谢博主哈~

      1. 梁Sir 2018-01-31 13:19:50 回复

        OK了

    1. fghrsh 2018-01-27 21:55:58 回复

      F12 有报错吗?

      1. heroyf 2018-01-28 22:47:41 回复

        没有报错啊

      1. 梁Sir 2018-01-28 16:36:44 回复

        同问此问题
        换装后隐身了 按F12查看
        提示live2d 模型 1-45 加载完成 waifu-tips.js:215:90
        Failed to load image : //api.fghrsh.net/live2d/get/../model/Potion-Maker/Pio/textures/sailor-costume-black.png live2d.js:1:139322

        1. fghrsh 2018-01-31 13:17:07 回复

          大概是源站防盗链问题,忘记设置了,现在再试试?

  1. HXC 2018-01-11 09:02:49 回复

    真不错,感谢分享

  1. 情醉中国风 2018-01-04 15:07:15 回复

    感谢分享,已经加上……

  1. 折影轻梦 2017-12-31 23:51:50 回复

    2018新年快乐!!!

    1. fghrsh 2017-12-31 23:56:14 回复

      (/≧▽≦)/ 同乐

  1. 小白-白 2017-12-22 00:09:53 回复

    都在玩这个。。。

发表我的评论

Hi,您需要填写昵称和邮箱!

  • 必填项
00:00 / 00:00
顺序播放