UNPKG

live2d-widgets

Version:
254 lines (242 loc) 6.58 kB
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>看板娘登陆平台</title> <link rel="stylesheet" href="https://fastly.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="https://fastly.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css"> <script src="../dist/live2d.min.js"></script> <style> html, body { height: 100%; } body { display: flex; align-items: center; justify-content: center; padding-top: 40px; padding-bottom: 40px; background-color: #f5f5f5; } .form-signin { width: 100%; max-width: 330px; padding: 15px; margin: 0 auto; } .form-signin .checkbox { font-weight: 400; } .form-signin .form-control { position: relative; box-sizing: border-box; height: auto; padding: 10px; font-size: 16px; } .form-signin .form-control:focus { z-index: 2; } .form-signin input[type=text] { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .form-signin input[type=password] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; } #stage { position: relative; } #stage img { width: 100%; margin-bottom: 20px; border-radius: 20px; } #stage button { position: absolute; padding: 0; } #inner { position: relative; background-color: #999; clip-path: circle(120px at center); } #cover { position: absolute; background-color: #CB3837; width: 100%; height: 100%; bottom: 0; transition: all 1s; box-shadow: 0 0 0 5px rgba(0, 0, 0, .1); overflow: hidden; } #text { position: absolute; font-size: 2em; opacity: 0.4; font-weight: bold; word-wrap: break-word; max-width: 100%; } #detail { position: absolute; background: rgba(255, 255, 255, .1); width: 100%; height: 10px; bottom: 0; } #handle { position: absolute; background: #ccc; bottom: -2px; box-shadow: 0 1px 0 1px rgba(0, 0, 0, .1); height: 8px; left: 50%; margin-left: -15px; width: 30px; cursor: pointer; } #info { left: 40px; bottom: 20px; } #refresh { right: 40px; bottom: 20px; } #live2d { cursor: grab; height: 300px; width: 300px; } #live2d:active { cursor: grabbing; } </style> </head> <body class="text-center"> <form class="form-signin" action="login.php" method="post"> <div id="stage"> <div id="inner"> <div id="cover"> <div id="text"></div> <div id="detail"></div> <div id="handle"></div> </div> <canvas class="mb-4" id="live2d" width="800" height="800"></canvas> </div> <button class="btn btn-link" id="info"><i class="fa fa-lg fa-info"></i></button> <button class="btn btn-link" id="refresh"><i class="fa fa-lg fa-sync-alt"></i></button> </div> <h1 class="h3 mb-3 fw-normal">看板娘登陆平台</h1> <label for="room" class="sr-only">用户名</label> <input type="text" name="room" class="form-control" placeholder="用户名" required autofocus> <label for="pass" class="sr-only">密码</label> <input type="password" name="pass" class="form-control" placeholder="密码" required> <div class="checkbox mb-4"> <input class="form-check-input me-1" type="checkbox" value="remember-me" id="remember-me"> <label class="form-check-label" for="remember-me">记住我</label> </div> <div class="d-grid"> <button class="btn btn-lg btn-primary" type="submit">登录</button> </div> <p class="mt-5 mb-3 text-muted">Copyleft &copy; Mimi <span id="year"></span></p> </form> <script type="module"> /* * _(:з」∠)_ * Created by Shuqiao Zhang in 2019. * https://zhangshuqiao.org */ /* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ import { Cubism2Model } from "../build/index.js"; document.getElementById("text").innerHTML = `<span style="color: cyan;">MIMI</span><span style="color: white;">POWERED</span>`.repeat(10); document.getElementById("year").innerText = new Date().getFullYear(); window.addEventListener("load", () => { if (!CSS.supports("clip-path", "circle(120px at center)")) { document.getElementById("stage").innerHTML = '<img src="./screenshots/screenshot-1.png">'; return; } const coverPosition = pos => document.getElementById("cover").style.bottom = pos; const apiPath = "https://live2d.fghrsh.net/api"; let state = 0, loading = false; const model = new Cubism2Model(); const modelId = 1; let modelTexturesId = 0; loadModel(); function setState(newState) { state = newState; if (state === 0) coverPosition("10%"); else if (state === 1) coverPosition("20%"); else if (state === 2) coverPosition("80%"); } async function loadModel() { const modelSettingPath = `${apiPath}/get/?id=${modelId}-${modelTexturesId}`; const response = await fetch(modelSettingPath); const modelSetting = await response.json(); if (!model.gl) { await model.init('live2d', modelSettingPath, modelSetting); } else { await model.changeModelWithJSON(modelSettingPath, modelSetting); } console.log("live2d", `模型 ${modelId}-${modelTexturesId} 加载完成`); setState(2); } async function loadRandModel() { const response = await fetch(`${apiPath}/rand_textures/?id=${modelId}-${modelTexturesId}`); const result = await response.json(); modelTexturesId = result.textures.id; await loadModel(); setState(2); } document.getElementById("info").addEventListener("click", () => { fetch("https://v1.hitokoto.cn") .then(response => response.json()) .then(result => { alert("「" + result.hitokoto + "」——" + result.from); }); }); document.getElementById("refresh").addEventListener("click", async () => { if (loading) return; loading = true; setState(0); await loadRandModel(); loading = false; }); document.getElementById("handle").addEventListener("click", () => { if (state === 1) { setState(2); } else if (state === 2) { setState(1); } }); document.querySelector("input[type=password]").addEventListener("focus", () => { if (state === 2) { setState(1); } }); document.querySelector("input[type=password]").addEventListener("blur", () => { if (state === 1) { setState(2); } }); }); </script> </body> </html>