您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show Dark Souls style location name popup on https://neal.fun/internet-roadtrip/
// ==UserScript== // @name Internet Roadtrip: Dark Souls Location Popup // @namespace http://tampermonkey.net/ // @version 1.1.2 // @author joawatte19 // @description Show Dark Souls style location name popup on https://neal.fun/internet-roadtrip/ // @match https://neal.fun/internet-roadtrip/ // @license MIT // @grant none // @run-at document-end // @require https://cdn.jsdelivr.net/npm/[email protected] // ==/UserScript== (async () => { if (!IRF?.isInternetRoadtrip) return; const container = await IRF.vdom.container; const originalUpdateData = container.methods.updateData; let lastLoc = {}; container.state.updateData = new Proxy(originalUpdateData, { apply: (target, thisArg, args) => { const result = Reflect.apply(target, thisArg, args); const loc = container.state.currentLocation; const fields = ["neighborhood", "county", "state", "country"]; let changedField = null; for (const field of fields) { if (loc?.[field] && loc[field] !== lastLoc[field]) { changedField = field; break; } } const changedValue = changedField ? loc[changedField] : null; lastLoc = { ...loc }; if (changedValue) { showPopup(changedValue); } return result; } }); function showPopup(text) { const existing = document.getElementById("ds-location-popup"); if (existing) existing.remove(); const overlay = document.createElement("div"); overlay.id = "ds-overlay"; Object.assign(overlay.style, { position: "fixed", top: "0", left: "0", width: "100vw", height: "100vh", backgroundColor: "#000", opacity: "0", zIndex: 9998, pointerEvents: "none", transition: "opacity 1.2s ease-in-out", }); document.body.appendChild(overlay); requestAnimationFrame(() => { overlay.style.opacity = "0.4"; }); const popup = document.createElement("div"); popup.id = "ds-location-popup"; popup.textContent = text; Object.assign(popup.style, { position: "fixed", top: "40%", left: "50%", transform: "translate(-50%, -50%) scale(0.95)", color: "#e3e2e0", fontFamily: "adobe-garamond-pro, Georgia, serif", fontSize: "4rem", whiteSpace: "nowrap", maxWidth: "90vw", userSelect: "none", zIndex: 9999, opacity: "0", textAlign: "center", lineHeight: "1.2", textShadow: "0 0 8px rgba(0,0,0,0.6), 0 0 2px #ccc", transition: "opacity 1.2s ease-in-out, transform 1.2s ease-in-out", pointerEvents: "none", padding: "1rem", paddingBottom: "0.05rem", borderBottom: "4px solid rgba(227,226,224,0.5)", }); document.body.appendChild(popup); // play sound const audio = new Audio("https://media.vocaroo.com/mp3/1f7euqkLrXJs"); audio.volume = 0.8; audio.play().catch(() => {}); // fade in requestAnimationFrame(() => { popup.style.opacity = "1"; popup.style.transform = "translate(-50%, -50%) scale(1)"; }); // fade out setTimeout(() => { popup.style.opacity = "0"; popup.style.transform = "translate(-50%, -50%) scale(1.05)"; overlay.style.opacity = "0"; setTimeout(() => { popup.remove(); overlay.remove(); }, 1500); }, 3000); } // manual trigger with console window.showDSLocationPopup = () => { const loc = container.state.currentLocation; if (!loc) { console.warn("No location data available."); return; } const fields = ["neighborhood", "county", "state", "country"]; for (const field of fields) { if (loc[field]) { showPopup(loc[field]); break; } } }; })();