diff --git a/asserts/css/live2dv3.init.css b/asserts/css/live2dv3.init.css new file mode 100644 index 0000000..bad91a0 --- /dev/null +++ b/asserts/css/live2dv3.init.css @@ -0,0 +1,317 @@ +#l2d-toggle { + background-color: #fa0; + border-radius: 5px; + bottom: 66px; + color: #fff; + cursor: pointer; + font-size: 12px; + left: 0; + margin-left: -100px; + padding: 5px 2px 5px 5px; + position: fixed; + transition: margin-left 1s; + width: 60px; + writing-mode: vertical-rl; +} + +#l2d-toggle.l2d-toggle-active { + margin-left: -50px; +} + +#l2d-toggle.l2d-toggle-active:hover { + margin-left: -30px; +} + +#l2d { + bottom: 0px; + left: 0; + line-height: 0; + position: fixed; + transform: translateY(3px); + transition: transform .3s ease-in-out, bottom 3s ease-in-out; + z-index: 1; +} + +#l2d:hover { + transform: translateY(0); +} + +@media (max-width: 768px) { + #l2d { + display: none; + } +} + +#L2dCanvas { + cursor: grab; + position: fixed; + bottom: 0px; + right: 0px; + right: -120px; + bottom: 5px; + z-index: 1; +} + +#L2dCanvas:active { + cursor: grabbing; +} + +#L2dCanvas #l2d-tips { + animation: shake 50s ease-in-out 5s infinite; + background-color: rgba(236, 217, 188, .5); + border: 1px solid rgba(224, 186, 140, .62); + border-radius: 12px; + box-shadow: 0 3px 15px 2px rgba(191, 158, 118, .2); + font-size: 14px; + line-height: 24px; + margin: -30px 20px; + min-height: 55px; + opacity: 0; + overflow: hidden; + padding: 5px 10px; + position: absolute; + bottom: 300px; + right: 110px; + text-overflow: ellipsis; + transition: opacity 1s; + width: 250px; + word-break: break-all; +} + +#L2dCanvas #l2d-tips.l2d-tips-active { + opacity: 1; + transition: opacity .2s; +} + +#L2dCanvas #l2d-tips span { + color: #0099cc; +} + +#L2dCanvas #l2d-tool { + color: #aaa; + opacity: 0; + position: absolute; + right: 125px; + bottom: 50px; + transition: opacity 1s; + z-index: 100; +} + +.l2d #L2dCanvas:hover #l2d-tool { + opacity: 1; +} + +#L2dCanvas #l2d-tool span { + color: #5b6c7d; + cursor: pointer; + display: block; + line-height: 30px; + text-align: center; + transition: color .3s; +} + +#L2dCanvas #l2d-tool span:hover { + color: #0684bd; /* #34495e */ +} + +@keyframes shake { + 2% { + transform: translate(.5px, -1.5px) rotate(-.5deg); + } + + 4% { + transform: translate(.5px, 1.5px) rotate(1.5deg); + } + + 6% { + transform: translate(1.5px, 1.5px) rotate(1.5deg); + } + + 8% { + transform: translate(2.5px, 1.5px) rotate(.5deg); + } + + 10% { + transform: translate(.5px, 2.5px) rotate(.5deg); + } + + 12% { + transform: translate(1.5px, 1.5px) rotate(.5deg); + } + + 14% { + transform: translate(.5px, .5px) rotate(.5deg); + } + + 16% { + transform: translate(-1.5px, -.5px) rotate(1.5deg); + } + + 18% { + transform: translate(.5px, .5px) rotate(1.5deg); + } + + 20% { + transform: translate(2.5px, 2.5px) rotate(1.5deg); + } + + 22% { + transform: translate(.5px, -1.5px) rotate(1.5deg); + } + + 24% { + transform: translate(-1.5px, 1.5px) rotate(-.5deg); + } + + 26% { + transform: translate(1.5px, .5px) rotate(1.5deg); + } + + 28% { + transform: translate(-.5px, -.5px) rotate(-.5deg); + } + + 30% { + transform: translate(1.5px, -.5px) rotate(-.5deg); + } + + 32% { + transform: translate(2.5px, -1.5px) rotate(1.5deg); + } + + 34% { + transform: translate(2.5px, 2.5px) rotate(-.5deg); + } + + 36% { + transform: translate(.5px, -1.5px) rotate(.5deg); + } + + 38% { + transform: translate(2.5px, -.5px) rotate(-.5deg); + } + + 40% { + transform: translate(-.5px, 2.5px) rotate(.5deg); + } + + 42% { + transform: translate(-1.5px, 2.5px) rotate(.5deg); + } + + 44% { + transform: translate(-1.5px, 1.5px) rotate(.5deg); + } + + 46% { + transform: translate(1.5px, -.5px) rotate(-.5deg); + } + + 48% { + transform: translate(2.5px, -.5px) rotate(.5deg); + } + + 50% { + transform: translate(-1.5px, 1.5px) rotate(.5deg); + } + + 52% { + transform: translate(-.5px, 1.5px) rotate(.5deg); + } + + 54% { + transform: translate(-1.5px, 1.5px) rotate(.5deg); + } + + 56% { + transform: translate(.5px, 2.5px) rotate(1.5deg); + } + + 58% { + transform: translate(2.5px, 2.5px) rotate(.5deg); + } + + 60% { + transform: translate(2.5px, -1.5px) rotate(1.5deg); + } + + 62% { + transform: translate(-1.5px, .5px) rotate(1.5deg); + } + + 64% { + transform: translate(-1.5px, 1.5px) rotate(1.5deg); + } + + 66% { + transform: translate(.5px, 2.5px) rotate(1.5deg); + } + + 68% { + transform: translate(2.5px, -1.5px) rotate(1.5deg); + } + + 70% { + transform: translate(2.5px, 2.5px) rotate(.5deg); + } + + 72% { + transform: translate(-.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(.5deg); + } + + 80% { + transform: translate(-1.5px, .5px) rotate(-.5deg); + } + + 82% { + transform: translate(-1.5px, .5px) rotate(-.5deg); + } + + 84% { + transform: translate(-.5px, .5px) rotate(1.5deg); + } + + 86% { + transform: translate(2.5px, 1.5px) rotate(.5deg); + } + + 88% { + transform: translate(-1.5px, .5px) rotate(1.5deg); + } + + 90% { + transform: translate(-1.5px, -.5px) rotate(-.5deg); + } + + 92% { + transform: translate(-1.5px, -1.5px) rotate(1.5deg); + } + + 94% { + transform: translate(.5px, .5px) rotate(-.5deg); + } + + 96% { + transform: translate(2.5px, -.5px) rotate(-.5deg); + } + + 98% { + transform: translate(-1.5px, -1.5px) rotate(-.5deg); + } + + 0%, 100% { + transform: translate(0, 0) rotate(0); + } +} diff --git a/asserts/js/charData.js b/asserts/js/charData.js new file mode 100644 index 0000000..112f68f --- /dev/null +++ b/asserts/js/charData.js @@ -0,0 +1,33 @@ +// 角色列表 +var charData = { + "Sirius (Midsummer Seirios)": "tianlangxing_3", + "Bismarck (Majesty of the Ironblood)": "bisimai_2", + "Ark Royal (Banquet Guardian)": "huangjiafangzhou_3", + "Taihou (Forbidden Feast)": "dafeng_2", + "Atago (Midsummer March)": "aidang_2", + "Eldridge (New Year's Handholding)": "aierdeliqi_4", + "Emile Bertin (Côte d'Azur)": "aimierbeierding_2", + "Centaur (Undine of the Beach)": "banrenma_2", + "Belfast (Iridescent Rose)": "beierfasite_2", + "Javelin": "biaoqiang", + "Javelin (Beach Picnic!)": "biaoqiang_3", + "Fubuki (Music Pixy)": "chuixue_3", + "Deutschland (Service Time?!)": "deyizhi_3", + "Unicorn (Amusement Park Date)": "dujiaoshou_4", + "Dunkerque (Summer Sucré)": "dunkeerke_2", + "Honolulu (Summer Accident?!)": "huonululu_3", + "Cleveland (Gentry Knight)": "kelifulan_3", + "Laffey": "lafei", + "Laffey (New Year Rabbit)": "lafei_4", + "Ayanami": "lingbo", + "Akashi": "mingshi", + "Graf Zeppelin (Beachside Urd)": "qibolin_2", + "St. Louis (Splendor of Spring)": "shengluyisi_2", + "St. Louis (Tipsy Snow)": "shengluyisi_3", + "Tai Yuan (Clamorous Tortoise)": "taiyuan_2", + "Tirpitz (Snow-melting Summer)": "tierbici_2", + "Yukikaze": "xuefeng", + "Ibuki (Wish of a Snow Goddess)": "yichui_2", + "Z23": "z23", + "Z46 (First Summer)": "z46_2", +}; \ No newline at end of file diff --git a/asserts/js/live2dv3.init.js b/asserts/js/live2dv3.init.js index 8dc4444..7d5d5a1 100644 --- a/asserts/js/live2dv3.init.js +++ b/asserts/js/live2dv3.init.js @@ -1,4 +1,23 @@ -document.write('
'); +// 创建看板娘div +document.body.insertAdjacentHTML("beforeend", + `
+ 看版娘 +
+
+
+
+ + + + + + + +
+
hello word
+
+
`); + // 依赖js // 兼容低版本浏览器 document.write(''); @@ -9,22 +28,137 @@ document.write(''); // live2dv3.js document.write(''); -var l2dv +// 内置角色 +document.write(''); + window.onload = () => { - l2dv = new l2dViewer({ - el: document.getElementById('L2dCanvas'), // 要添加Live2d的元素 - basePath: 'https://cdn.jsdelivr.net/gh/alg-wiki/AzurLaneL2DViewer@gh-pages/assets', // 模型根目录 - modelName: 'dujiaoshou_6', // 模型名称 - sounds: [ // 触摸播放声音 - 'sounds/demo.mp3', // 相对路径是相对于模型文件夹 - 'https://cdn.jsdelivr.net/npm/live2dv3@latest/assets/biaoqiang_3/sounds/demo.mp3' // 也可以是网址 - ] - }) -} - -function loadModel() { - var modelName = document.getElementById('modelName').value + createL2dv(); +} + +// 创建l2dv +var l2dv +function createL2dv() { + if(!l2dv) { + l2dv = new l2dViewer({ + el: document.getElementById('L2dCanvas'), // 要添加Live2d的元素 + basePath: 'https://cdn.jsdelivr.net/gh/alg-wiki/AzurLaneL2DViewer@gh-pages/assets', // 模型根目录 + modelName: 'dujiaoshou_6', // 模型名称 + sounds: [ // 触摸播放声音 + 'sounds/demo.mp3', // 相对路径是相对于模型文件夹 + 'https://cdn.jsdelivr.net/npm/live2dv3@latest/assets/biaoqiang_3/sounds/demo.mp3' // 也可以是网址 + ] + }) + } + // 注册事件 + registerEventListener(); +} + +// 监听事件 +function registerEventListener() { + const click_tips = ["干嘛呢你,快把手拿开~~", "鼠…鼠标放错地方了!", "你要干嘛呀?", "喵喵喵?", "怕怕(ノ≧∇≦)ノ", "非礼呀!救命!", "这样的话,只能使用武力了!", "我要生气了哦", "不要动手动脚的!", "真…真的是不知羞耻!", "Hentai!"] + document.querySelector("#L2dCanvas canvas").addEventListener("click", () => { + showMessage(click_tips[click_tips.length * Math.random() << 0], 1000) + }); + + // tool click event + document.querySelector("#l2d-tool .fa-comment").addEventListener("click", showHitokoto); + document.querySelector("#l2d-tool .fa-paper-plane").addEventListener("click", () => { + showMessage("功能待定"); + }); + document.querySelector("#l2d-tool .fa-user-circle").addEventListener("click", loadModel); + document.querySelector("#l2d-tool .fa-street-view").addEventListener("click", loadModel); + document.querySelector("#l2d-tool .fa-camera-retro").addEventListener("click", () => { + showMessage("功能待定"); + }); + document.querySelector("#l2d-tool .fa-info-circle").addEventListener("click", () => { + open("https://github.com/jianchengwang/live2d_models"); + }); + document.querySelector("#l2d-tool .fa-times").addEventListener("click", hideModel); + + // toogle click event + document.getElementById("l2d-toggle").addEventListener("click", showModel); + + // other + const devtools = () => {}; + console.log("%c", devtools); + devtools.toString = () => { + showMessage("哈哈,你打开了控制台,是想要看看我的小秘密吗?", 4000, 9); + }; + window.addEventListener("copy", () => { + showMessage("你都复制了些什么呀,转载要记得加上出处哦!", 4000, 9); + }); + window.addEventListener("visibilitychange", () => { + if (!document.hidden) showMessage("哇,你终于回来了~", 4000, 9); + }); +} + +// 显示模型 +function hideModel(l2d_toggle) { + showMessage("愿你有一天能与重要的人重逢。", 2000, 11); + setTimeout(() => { + document.getElementById("L2dCanvas").style.bottom = "-500px"; + document.getElementById("L2dCanvas").style.display = "none"; + document.getElementById("l2d-toggle").classList.add("l2d-toggle-active"); + }, 3000); +} + +// 隐藏模型 +function showModel() { + const l2d_toggle = document.getElementById("l2d-toggle"); + l2d_toggle.classList.remove("l2d-toggle-active"); + document.getElementById("L2dCanvas").style.display = ""; + setTimeout(() => { + document.getElementById("L2dCanvas").style.bottom = 0; + showMessage("萌萌哒看板娘已上线", 3000, 11); + }, 500); +} + +// 加载model +function loadModel(modelName) { + showMessage("正在切换看板娘...", 6000, 1); + if(modelName instanceof MouseEvent) { + modelName = randomChar(); + } else if(!modelName) { + if(document.getElementById('modelName')) { + modelName = document.getElementById('modelName').value + } else { + modelName = randomChar(); + } + } console.info(modelName + ' loading....' ) l2dv.loadModel(modelName) } + +// 随机选择角色模型 +function randomChar() { + var keys = Object.keys(charData) + return charData[keys[keys.length * Math.random() << 0]]; +}; + +// 显示一句一言 +function showHitokoto() { + // 增加 hitokoto.cn 的 API + fetch("https://v1.hitokoto.cn") + .then(response => response.json()) + .then(result => { + const text = `这句一言来自 「${result.from}」,是 ${result.creator} 在 hitokoto.cn 投稿的。`; + showMessage(result.hitokoto, 6000, 9); + setTimeout(() => { + showMessage(text, 4000, 9); + }, 6000); + }); +} + +// 显示tip消息 +function showMessage(text, timeout, priority) { + if (!text) return; + if(!timeout) timeout = 1000; + const tips = document.getElementById("l2d-tips"); + tips.innerHTML = text; + tips.classList.add("l2d-tips-active"); + messageTimer = setTimeout(() => { + sessionStorage.removeItem("l2d-text"); + tips.classList.remove("l2d-tips-active"); + }, timeout); +} \ No newline at end of file diff --git a/index.html b/index.html index 18c567d..9bf4e72 100644 --- a/index.html +++ b/index.html @@ -6,66 +6,28 @@ live2d-v3-demo - u can find more model from https://github.com/Yukariin/AzurLaneL2DViewer

-
-
- - - - -
-
-
想阅读 “Element Upload 组件上传多文件的坑” 吗?
+ +
+
+
+ + + + + + + +
+
如果有疑问,请尽快留言哦~
+
+
--> +
@@ -89,13 +51,7 @@ modelName: 'bisimai_2', sounds: [ ] - }) - } - - function loadModel() { - var modelName = document.getElementById('modelName').value - console.info(modelName + ' loading....' ) - l2dv.loadModel(modelName) + }); } \ No newline at end of file diff --git a/index2.html b/index2.html index 1bf0ef3..79cd45c 100644 --- a/index2.html +++ b/index2.html @@ -4,12 +4,17 @@ live2d-v3-demo + + u can find more model from https://github.com/Yukariin/AzurLaneL2DViewer
-
+ + +
\ No newline at end of file