This commit is contained in:
2025-12-08 01:03:07 +08:00
commit 5c77d25b6d
334 changed files with 71475 additions and 0 deletions

359
public/pio/static/pio.js Normal file
View File

@@ -0,0 +1,359 @@
/* ----
# Pio Plugin
# By: Dreamer-Paul
# Last Update: 2022.8.12
一个支持更换 Live2D 模型的 JS 插件
本代码为奇趣保罗原创,并遵守 GPL 2.0 开源协议。欢迎访问我的博客https://paugram.com
---- */
var Paul_Pio = function (prop) {
const current = {
idol: 0,
timeout: undefined,
menu: document.querySelector(".pio-container .pio-action"),
canvas: document.getElementById("pio"),
body: document.querySelector(".pio-container"),
root: document.location.origin + "/",
};
// 工具通用函数
const tools = {
// 创建内容
create: (tag, options) => {
const el = document.createElement(tag);
options.class && (el.className = options.class);
return el;
},
// 随机内容
rand: (arr) => {
return arr[Math.floor(Math.random() * arr.length + 1) - 1];
},
// 是否为移动设备
isMobile: () => {
let ua = window.navigator.userAgent.toLowerCase();
ua = ua.indexOf("mobile") || ua.indexOf("android") || ua.indexOf("ios");
return window.innerWidth < 500 || ua !== -1;
},
};
const elements = {
home: tools.create("span", { class: "pio-home" }),
skin: tools.create("span", { class: "pio-skin" }),
info: tools.create("span", { class: "pio-info" }),
night: tools.create("span", { class: "pio-night" }),
close: tools.create("span", { class: "pio-close" }),
dialog: tools.create("div", { class: "pio-dialog" }),
show: tools.create("div", { class: "pio-show" }),
};
current.body.appendChild(elements.dialog);
current.body.appendChild(elements.show);
/* - 方法 */
const modules = {
// 更换模型
idol: () => {
current.idol < prop.model.length - 1
? current.idol++
: (current.idol = 0);
return current.idol;
},
// 创建对话框方法
message: (text, options = {}) => {
const { dialog } = elements;
if (text.constructor === Array) {
dialog.innerText = tools.rand(text);
} else if (text.constructor === String) {
dialog[options.html ? "innerHTML" : "innerText"] = text;
} else {
dialog.innerText = "输入内容出现问题了 X_X";
}
dialog.classList.add("active");
current.timeout = clearTimeout(current.timeout) || undefined;
current.timeout = setTimeout(() => {
dialog.classList.remove("active");
}, options.time || 3000);
},
// 移除方法
destroy: () => {
this.initHidden();
localStorage.setItem("posterGirl", "0");
},
};
this.destroy = modules.destroy;
this.message = modules.message;
/* - 提示操作 */
const action = {
// 欢迎
welcome: () => {
if (document.referrer && document.referrer.includes(current.root)) {
const referrer = document.createElement("a");
referrer.href = document.referrer;
if (prop.content.referer) {
modules.message(
prop.content.referer.replace(/%t/, `${referrer.hostname}`),
);
} else {
modules.message(`欢迎来自 “${referrer.hostname}” 的朋友!`);
}
} else if (prop.tips) {
let text,
hour = new Date().getHours();
if (hour > 22 || hour <= 5) {
text = "你是夜猫子呀?这么晚还不睡觉,明天起的来嘛";
} else if (hour > 5 && hour <= 8) {
text = "早上好!";
} else if (hour > 8 && hour <= 11) {
text = "上午好!工作顺利嘛,不要久坐,多起来走动走动哦!";
} else if (hour > 11 && hour <= 14) {
text = "中午了,工作了一个上午,现在是午餐时间!";
} else if (hour > 14 && hour <= 17) {
text = "午后很容易犯困呢,今天的运动目标完成了吗?";
} else if (hour > 17 && hour <= 19) {
text = "傍晚了!窗外夕阳的景色很美丽呢,最美不过夕阳红~";
} else if (hour > 19 && hour <= 21) {
text = "晚上好,今天过得怎么样?";
} else if (hour > 21 && hour <= 23) {
text = "已经这么晚了呀,早点休息吧,晚安~";
} else {
text = "奇趣保罗说:这个是无法被触发的吧,哈哈";
}
modules.message(text);
} else {
modules.message(prop.content.welcome || "欢迎来到本站!");
}
},
// 触摸
touch: () => {
current.canvas.onclick = () => {
modules.message(
prop.content.touch || [
"你在干什么?",
"再摸我就报警了!",
"HENTAI!",
"不可以这样欺负我啦!",
],
);
};
},
// 右侧按钮
buttons: () => {
// 返回首页 - 使用 Swup 无刷新跳转
elements.home.onclick = () => {
// 检查 Swup 是否可用
if (typeof window !== "undefined" && window.swup) {
try {
// 使用 Swup 进行无刷新跳转
window.swup.navigate("/");
} catch (error) {
console.error("Swup navigation failed:", error);
// 降级到普通跳转
location.href = current.root;
}
} else {
// Swup 不可用时使用普通跳转
location.href = current.root;
}
};
elements.home.onmouseover = () => {
modules.message(prop.content.home || "点击这里回到首页!");
};
current.menu.appendChild(elements.home);
// 更换模型
if (prop.model && prop.model.length > 1) {
elements.skin.onclick = () => {
loadlive2d("pio", prop.model[modules.idol()]);
prop.content.skin &&
modules.message(prop.content.skin[1] || "新衣服真漂亮~");
};
elements.skin.onmouseover = () => {
prop.content.skin &&
modules.message(prop.content.skin[0] || "想看看我的新衣服吗?");
};
current.menu.appendChild(elements.skin);
}
// 关于我
elements.info.onclick = () => {
window.open(
prop.content.link ||
"https://paugram.com/coding/add-poster-girl-with-plugin.html",
);
};
elements.info.onmouseover = () => {
modules.message("想了解更多关于我的信息吗?");
};
current.menu.appendChild(elements.info);
// 夜间模式
if (prop.night) {
elements.night.onclick = () => {
typeof prop.night === "function" ? prop.night() : eval(prop.night);
};
elements.night.onmouseover = () => {
modules.message("夜间点击这里可以保护眼睛呢");
};
current.menu.appendChild(elements.night);
}
// 关闭看板娘
elements.close.onclick = () => {
modules.destroy();
};
elements.close.onmouseover = () => {
modules.message(prop.content.close || "QWQ 下次再见吧~");
};
current.menu.appendChild(elements.close);
},
// 自定义选择器
custom: () => {
prop.content.custom.forEach((item) => {
const el = document.querySelectorAll(item.selector);
if (!el.length) return;
for (let i = 0; i < el.length; i++) {
if (item.type === "read") {
el[i].onmouseover = (ev) => {
const text = ev.currentTarget.title || ev.currentTarget.innerText;
modules.message("想阅读 %t 吗?".replace(/%t/, "“" + text + "”"));
};
} else if (item.type === "link") {
el[i].onmouseover = (ev) => {
const text = ev.currentTarget.title || ev.currentTarget.innerText;
modules.message(
"想了解一下 %t 吗?".replace(/%t/, "“" + text + "”"),
);
};
} else if (item.text) {
el[i].onmouseover = () => {
modules.message(t.text);
};
}
}
});
},
};
/* - 运行 */
const begin = {
static: () => {
current.body.classList.add("static");
},
fixed: () => {
action.touch();
action.buttons();
},
draggable: () => {
action.touch();
action.buttons();
const body = current.body;
const location = {
x: 0,
y: 0,
};
const mousedown = (ev) => {
const { offsetLeft, offsetTop } = ev.currentTarget;
location.x = ev.clientX - offsetLeft;
location.y = ev.clientY - offsetTop;
document.addEventListener("mousemove", mousemove);
document.addEventListener("mouseup", mouseup);
};
const mousemove = (ev) => {
body.classList.add("active");
body.classList.remove("right");
body.style.left = ev.clientX - location.x + "px";
body.style.top = ev.clientY - location.y + "px";
body.style.bottom = "auto";
};
const mouseup = () => {
body.classList.remove("active");
document.removeEventListener("mousemove", mousemove);
};
body.onmousedown = mousedown;
},
};
// 运行
this.init = (noModel) => {
// 未隐藏 + 非手机版,出现操作功能
if (!(prop.hidden && tools.isMobile())) {
if (!noModel) {
action.welcome();
loadlive2d("pio", prop.model[0]);
}
switch (prop.mode) {
case "static":
begin.static();
break;
case "fixed":
begin.fixed();
break;
case "draggable":
begin.draggable();
break;
}
prop.content.custom && action.custom();
}
};
// 隐藏状态
this.initHidden = () => {
// ! 清除预设好的间距
if (prop.mode === "draggable") {
current.body.style.top = null;
current.body.style.left = null;
current.body.style.bottom = null;
}
current.body.classList.add("hidden");
elements.dialog.classList.remove("active");
elements.show.onclick = () => {
current.body.classList.remove("hidden");
localStorage.setItem("posterGirl", "1");
this.init();
};
};
localStorage.getItem("posterGirl") === "0" ? this.initHidden() : this.init();
};
// 请保留版权说明
if (window.console && window.console.log) {
console.log(
"%c Pio %c https://paugram.com ",
"color: #fff; margin: 1em 0; padding: 5px 0; background: #673ab7;",
"margin: 1em 0; padding: 5px 0; background: #efefef;",
);
}