MediaWiki:Common.js: различия между версиями
Mei Day (обсуждение | вклад) м Защитил страницу MediaWiki:Common.js ([Редактирование=Разрешено только администраторам] (бессрочно) [Переименование=Разрешено только администраторам] (бессрочно)) |
Mei Day (обсуждение | вклад) Нет описания правки |
||
| Строка 151: | Строка 151: | ||
/* ---- Server online status ---- */ | /* ---- Server online status ---- */ | ||
/* Queries /api/status.php on the same wiki host — which sends a UDP BYOND | |||
* topic to localhost:41060 and returns JSON { players, map_name, ... }. | |||
* No proxy needed: wiki and game server share the same machine. | |||
*/ | |||
(function () { | (function () { | ||
"use strict"; | "use strict"; | ||
var el = document.getElementById("orb-online"); | var el = document.getElementById("orb-online"); | ||
if (!el) return; | if (!el) return; | ||
// | |||
// Same-origin request — status.php sits next to the wiki | |||
// fetch(STATUS_URL) | var STATUS_URL = "/api/status.php"; | ||
var REFRESH_MS = 30000; // refresh every 30 seconds | |||
function update() { | |||
fetch(STATUS_URL) | |||
.then(function (r) { | |||
if (!r.ok) throw new Error(r.status); | |||
return r.json(); | |||
}) | |||
.then(function (data) { | |||
var count = parseInt(data.players, 10); | |||
if (isNaN(count)) throw new Error("bad data"); | |||
el.textContent = count + " онлайн"; | |||
el.style.color = | |||
count > 0 | |||
? "rgba(100,220,180,0.75)" | |||
: "rgba(100,220,180,0.35)"; | |||
el.style.textShadow = | |||
count > 0 | |||
? "0 0 15px rgba(100,220,180,0.2)" | |||
: "none"; | |||
}) | |||
.catch(function () { | |||
el.textContent = "оффлайн"; | |||
el.style.color = "rgba(255,120,120,0.5)"; | |||
el.style.textShadow = "none"; | |||
}); | |||
} | |||
update(); | |||
setInterval(update, REFRESH_MS); | |||
})(); | })(); | ||
| Строка 262: | Строка 284: | ||
addr.style.cursor = "pointer"; | addr.style.cursor = "pointer"; | ||
addr.addEventListener("click", function () { | addr.addEventListener("click", function () { | ||
window.location.href = "byond:// | window.location.href = "byond://45.141.208.222:41060"; | ||
}); | }); | ||
addr.addEventListener("mouseenter", function () { | addr.addEventListener("mouseenter", function () { | ||
| Строка 274: | Строка 296: | ||
} | } | ||
/* BYOND | /* Utility buttons (BYOND, Discord, Proxy) */ | ||
var | var utilBtns = ["orb-btn-byond", "orb-btn-discord", "orb-btn-proxy"]; | ||
for (var k = 0; k < utilBtns.length; k++) { | |||
var btn = document.getElementById(utilBtns[k]); | |||
if (btn) { | |||
btn.style.setProperty( | |||
"border", | |||
"1px solid rgba(255,255,255,0.07)", | |||
"important", | |||
); | |||
btn.style.setProperty("border-radius", "4px", "important"); | |||
btn.style.setProperty( | |||
"background", | |||
"rgba(255,255,255,0.02)", | |||
"important", | |||
); | |||
} | |||
} | } | ||
| Строка 324: | Строка 349: | ||
"border-left", | "border-left", | ||
"2px solid " + c(rgb, baseOp), | "2px solid " + c(rgb, baseOp), | ||
"important" | "important", | ||
); | ); | ||
el.style.setProperty( | el.style.setProperty( | ||
"background", | "background", | ||
"linear-gradient(90deg, " + c(rgb, gradOp) + " 0%, transparent 70%)", | "linear-gradient(90deg, " + c(rgb, gradOp) + " 0%, transparent 70%)", | ||
"important" | "important", | ||
); | ); | ||
el.style.borderRadius = "0 4px 4px 0"; | el.style.borderRadius = "0 4px 4px 0"; | ||
| Строка 337: | Строка 362: | ||
this.style.setProperty( | this.style.setProperty( | ||
"background", | "background", | ||
"linear-gradient(90deg, " + c(rgb, 0.08) + " 0%, " + c(rgb, 0.02) + " 60%, transparent 100%)", | "linear-gradient(90deg, " + | ||
"important" | c(rgb, 0.08) + | ||
" 0%, " + | |||
c(rgb, 0.02) + | |||
" 60%, transparent 100%)", | |||
"important", | |||
); | ); | ||
this.style.setProperty("border-left-color", c(rgb, 0.6), "important"); | this.style.setProperty("border-left-color", c(rgb, 0.6), "important"); | ||
| Строка 347: | Строка 376: | ||
", 0 0 25px " + | ", 0 0 25px " + | ||
c(rgb, 0.04), | c(rgb, 0.04), | ||
"important" | "important", | ||
); | ); | ||
}); | }); | ||
| Строка 354: | Строка 383: | ||
"background", | "background", | ||
"linear-gradient(90deg, " + c(rgb, gradOp) + " 0%, transparent 70%)", | "linear-gradient(90deg, " + c(rgb, gradOp) + " 0%, transparent 70%)", | ||
"important" | "important", | ||
); | ); | ||
this.style.setProperty( | this.style.setProperty( | ||
"border-left-color", | "border-left-color", | ||
c(rgb, baseOp), | c(rgb, baseOp), | ||
"important" | "important", | ||
); | ); | ||
this.style.setProperty("box-shadow", "none", "important"); | this.style.setProperty("box-shadow", "none", "important"); | ||
| Строка 369: | Строка 398: | ||
el.addEventListener("click", function (ev) { | el.addEventListener("click", function (ev) { | ||
var t = ev.target; | var t = ev.target; | ||
if (t.tagName !== "A" && (!t.parentNode || t.parentNode.tagName !== "A")) { | if ( | ||
t.tagName !== "A" && | |||
(!t.parentNode || t.parentNode.tagName !== "A") | |||
) { | |||
a.click(); | a.click(); | ||
} | } | ||
Версия от 14:44, 3 марта 2026
/* MediaWiki:Common.js — Orbitalis Wiki
* This code runs on every wiki page.
* Paste this into MediaWiki:Common.js on the wiki (requires admin rights).
*
* Parallax space background that follows the mouse cursor,
* matching the in-game lobby style.
*/
(function () {
"use strict";
// Only activate on the main page (or everywhere — your choice)
var parallaxBg = document.getElementById("orbitalis-parallax-bg");
if (!parallaxBg) return; // no parallax container on this page
var nebulaEl = document.getElementById("parallax-nebula");
var starsSmallEl = document.getElementById("parallax-stars-small");
var starsBigEl = document.getElementById("parallax-stars-big");
// ---- Apply styles to the parallax elements ----------------------------
// We do it from JS because MediaWiki strips complex inline styles
// Background container
parallaxBg.style.cssText =
"position:fixed;top:0;left:0;width:100%;height:100%;z-index:0;pointer-events:none;overflow:hidden;background:#060608;";
// Shared layer base
var layerBase =
"position:fixed;top:-50px;left:-50px;width:calc(100% + 100px);height:calc(100% + 100px);pointer-events:none;";
// Nebula
if (nebulaEl) {
nebulaEl.style.cssText =
layerBase +
"background:" +
"radial-gradient(ellipse at 70% 40%, rgba(30,50,80,0.4) 0%, transparent 50%)," +
"radial-gradient(ellipse at 85% 60%, rgba(50,30,60,0.3) 0%, transparent 45%)," +
"radial-gradient(ellipse at 60% 70%, rgba(20,40,70,0.35) 0%, transparent 55%);" +
"opacity:0.7;z-index:0;";
}
// Small stars
if (starsSmallEl) {
starsSmallEl.style.cssText =
layerBase +
"background-image:" +
"radial-gradient(1px 1px at 10% 20%, rgba(255,255,255,0.8), transparent)," +
"radial-gradient(1px 1px at 25% 35%, rgba(255,255,255,0.6), transparent)," +
"radial-gradient(1px 1px at 40% 10%, rgba(255,255,255,0.7), transparent)," +
"radial-gradient(1px 1px at 55% 45%, rgba(255,255,255,0.5), transparent)," +
"radial-gradient(1px 1px at 70% 25%, rgba(255,255,255,0.8), transparent)," +
"radial-gradient(1px 1px at 85% 55%, rgba(255,255,255,0.6), transparent)," +
"radial-gradient(1px 1px at 15% 60%, rgba(255,255,255,0.7), transparent)," +
"radial-gradient(1px 1px at 30% 75%, rgba(255,255,255,0.5), transparent)," +
"radial-gradient(1px 1px at 45% 85%, rgba(255,255,255,0.8), transparent)," +
"radial-gradient(1px 1px at 60% 70%, rgba(255,255,255,0.6), transparent)," +
"radial-gradient(1px 1px at 75% 90%, rgba(255,255,255,0.7), transparent)," +
"radial-gradient(1px 1px at 90% 15%, rgba(255,255,255,0.5), transparent)," +
"radial-gradient(1px 1px at 5% 40%, rgba(255,255,255,0.6), transparent)," +
"radial-gradient(1px 1px at 20% 95%, rgba(255,255,255,0.7), transparent)," +
"radial-gradient(1px 1px at 35% 50%, rgba(255,255,255,0.5), transparent)," +
"radial-gradient(1px 1px at 50% 30%, rgba(255,255,255,0.8), transparent)," +
"radial-gradient(1px 1px at 65% 5%, rgba(255,255,255,0.6), transparent)," +
"radial-gradient(1px 1px at 80% 65%, rgba(255,255,255,0.7), transparent)," +
"radial-gradient(1px 1px at 95% 80%, rgba(255,255,255,0.5), transparent)," +
"radial-gradient(1px 1px at 12% 88%, rgba(255,255,255,0.6), transparent);" +
"background-size:200px 200px;opacity:0.8;z-index:1;";
}
// Big stars
if (starsBigEl) {
starsBigEl.style.cssText =
layerBase +
"background-image:" +
"radial-gradient(2px 2px at 8% 15%, rgba(200,220,255,0.9), transparent)," +
"radial-gradient(2px 2px at 22% 42%, rgba(255,240,220,0.8), transparent)," +
"radial-gradient(2px 2px at 38% 8%, rgba(220,255,255,0.7), transparent)," +
"radial-gradient(2px 2px at 52% 68%, rgba(255,255,220,0.8), transparent)," +
"radial-gradient(2px 2px at 68% 32%, rgba(200,200,255,0.9), transparent)," +
"radial-gradient(2px 2px at 82% 78%, rgba(255,220,200,0.7), transparent)," +
"radial-gradient(2px 2px at 18% 55%, rgba(220,255,220,0.8), transparent)," +
"radial-gradient(2px 2px at 48% 92%, rgba(255,200,255,0.7), transparent)," +
"radial-gradient(2px 2px at 72% 18%, rgba(200,255,255,0.8), transparent)," +
"radial-gradient(2px 2px at 92% 45%, rgba(255,255,200,0.7), transparent);" +
"background-size:300px 300px;opacity:0.6;z-index:2;";
}
// Vignette overlay
var vignetteEl = document.getElementById("orbitalis-vignette");
if (vignetteEl) {
vignetteEl.style.cssText =
"position:fixed;top:0;left:0;width:100%;height:100%;z-index:3;pointer-events:none;" +
"background:radial-gradient(ellipse at center, rgba(6,6,8,0) 30%, rgba(6,6,8,0.6) 70%, #060608 100%);";
}
// ---- Override MediaWiki default backgrounds ----------------------------
document.body.style.background = "#060608";
var ids = ["mw-page-base", "mw-head-base"];
for (var i = 0; i < ids.length; i++) {
var el = document.getElementById(ids[i]);
if (el) el.style.background = "none";
}
var content = document.getElementById("content");
if (content) {
content.style.background = "none";
content.style.border = "none";
}
var bodyContent = document.getElementById("bodyContent");
if (bodyContent) {
bodyContent.style.position = "relative";
bodyContent.style.zIndex = "5";
}
// ---- Mouse-tracking parallax animation --------------------------------
var targetX = 0,
targetY = 0;
var currentX = 0,
currentY = 0;
document.addEventListener("mousemove", function (e) {
var w = window.innerWidth || document.documentElement.clientWidth;
var h = window.innerHeight || document.documentElement.clientHeight;
targetX = (e.clientX / w - 0.5) * 2;
targetY = (e.clientY / h - 0.5) * 2;
});
function animate() {
currentX += (targetX - currentX) * 0.06;
currentY += (targetY - currentY) * 0.06;
if (nebulaEl) {
nebulaEl.style.left = currentX * 12 - 50 + "px";
nebulaEl.style.top = currentY * 12 - 50 + "px";
}
if (starsSmallEl) {
starsSmallEl.style.left = currentX * 25 - 50 + "px";
starsSmallEl.style.top = currentY * 25 - 50 + "px";
}
if (starsBigEl) {
starsBigEl.style.left = currentX * 40 - 50 + "px";
starsBigEl.style.top = currentY * 40 - 50 + "px";
}
requestAnimationFrame(animate);
}
animate();
})();
/* ---- Server online status ---- */
/* Queries /api/status.php on the same wiki host — which sends a UDP BYOND
* topic to localhost:41060 and returns JSON { players, map_name, ... }.
* No proxy needed: wiki and game server share the same machine.
*/
(function () {
"use strict";
var el = document.getElementById("orb-online");
if (!el) return;
// Same-origin request — status.php sits next to the wiki
var STATUS_URL = "/api/status.php";
var REFRESH_MS = 30000; // refresh every 30 seconds
function update() {
fetch(STATUS_URL)
.then(function (r) {
if (!r.ok) throw new Error(r.status);
return r.json();
})
.then(function (data) {
var count = parseInt(data.players, 10);
if (isNaN(count)) throw new Error("bad data");
el.textContent = count + " онлайн";
el.style.color =
count > 0
? "rgba(100,220,180,0.75)"
: "rgba(100,220,180,0.35)";
el.style.textShadow =
count > 0
? "0 0 15px rgba(100,220,180,0.2)"
: "none";
})
.catch(function () {
el.textContent = "оффлайн";
el.style.color = "rgba(255,120,120,0.5)";
el.style.textShadow = "none";
});
}
update();
setInterval(update, REFRESH_MS);
})();
/* ---- Main page: visual design engine ---- */
/* Injects styles AFTER Citizen skin + does direct DOM manipulation.
This guarantees we override any skin-applied link backgrounds. */
(function () {
"use strict";
/* 1. Inject a <style> tag that appends AFTER all skin stylesheets */
var css = document.createElement("style");
css.id = "orb-override";
css.textContent =
"#orb-content a,#orb-content a:link,#orb-content a:visited," +
"#orb-content a:hover,#orb-content a:active,#orb-content a:focus{" +
"background:none!important;background-color:transparent!important;" +
"background-image:none!important;box-shadow:none!important;" +
"border:none!important;border-bottom:none!important;" +
"padding:0!important;text-decoration:none!important;" +
"outline:none!important;-webkit-text-decoration:none!important}" +
"#orb-content small{display:block;margin-top:3px}" +
"[id^='orb-card-']{transition:border-color .25s,box-shadow .25s,background .25s!important}";
document.head.appendChild(css);
/* 2. DOM styling — runs after content is ready */
var done = false;
function run() {
var orb = document.getElementById("orb-content");
if (!orb || done) return;
done = true;
/* Colour palette */
var B = [91, 141, 239],
P = [180, 130, 255],
T = [100, 220, 180];
function c(rgb, a) {
return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")";
}
/* NUCLEAR: strip every background & shadow from every element inside */
var all = orb.querySelectorAll("*");
for (var i = 0; i < all.length; i++) {
var e = all[i];
e.style.setProperty("background", "none", "important");
e.style.setProperty("background-color", "transparent", "important");
e.style.setProperty("background-image", "none", "important");
e.style.setProperty("box-shadow", "none", "important");
if (e.tagName === "A") {
e.style.setProperty("border", "none", "important");
e.style.setProperty("padding", "0", "important");
e.style.setProperty("text-decoration", "none", "important");
}
}
/* Description block */
var desc = document.getElementById("orb-desc");
if (desc) {
desc.style.borderLeft = "2px solid " + c(B, 0.2);
}
/* Section titles + decorative underline */
styleTitle("orb-title-docs", B);
styleTitle("orb-title-play", P);
/* Link cards */
var dC = ["orb-card-1", "orb-card-2", "orb-card-3", "orb-card-4"];
var pC = ["orb-card-5", "orb-card-6", "orb-card-7", "orb-card-8"];
for (var j = 0; j < 4; j++) {
styleCard(dC[j], B, j);
styleCard(pC[j], P, j);
}
/* Server block */
var srv = document.getElementById("orb-server");
if (srv) {
srv.style.borderLeft = "2px solid " + c(T, 0.3);
srv.style.borderRadius = "0 4px 4px 0";
}
var onl = document.getElementById("orb-online");
if (onl) {
onl.style.color = c(T, 0.55);
onl.style.textShadow = "0 0 15px " + c(T, 0.15);
}
/* Connect button — clickable byond:// link */
var addr = document.getElementById("orb-addr");
if (addr) {
addr.style.setProperty("border", "1px solid " + c(T, 0.25), "important");
addr.style.setProperty("border-radius", "4px", "important");
addr.style.setProperty("background", c(T, 0.06), "important");
addr.style.color = c(T, 0.7);
addr.style.cursor = "pointer";
addr.addEventListener("click", function () {
window.location.href = "byond://45.141.208.222:41060";
});
addr.addEventListener("mouseenter", function () {
this.style.setProperty("background", c(T, 0.12), "important");
this.style.setProperty("border-color", c(T, 0.4), "important");
});
addr.addEventListener("mouseleave", function () {
this.style.setProperty("background", c(T, 0.06), "important");
this.style.setProperty("border-color", c(T, 0.25), "important");
});
}
/* Utility buttons (BYOND, Discord, Proxy) */
var utilBtns = ["orb-btn-byond", "orb-btn-discord", "orb-btn-proxy"];
for (var k = 0; k < utilBtns.length; k++) {
var btn = document.getElementById(utilBtns[k]);
if (btn) {
btn.style.setProperty(
"border",
"1px solid rgba(255,255,255,0.07)",
"important",
);
btn.style.setProperty("border-radius", "4px", "important");
btn.style.setProperty(
"background",
"rgba(255,255,255,0.02)",
"important",
);
}
}
/* Footer divider */
var foot = document.getElementById("orb-footer");
if (foot) foot.style.borderTop = "1px solid rgba(255,255,255,0.04)";
/* ---- helper: section title ---- */
function styleTitle(id, rgb) {
var el = document.getElementById(id);
if (!el) return;
el.style.color = c(rgb, 0.8);
el.style.textShadow = "0 0 25px " + c(rgb, 0.2);
/* decorative underline bar */
if (!el.querySelector(".orb-ul")) {
var ln = document.createElement("div");
ln.className = "orb-ul";
ln.style.cssText =
"width:40px;height:1px;margin-top:10px;" +
"background:" +
c(rgb, 0.35) +
";box-shadow:0 0 12px " +
c(rgb, 0.12);
el.appendChild(ln);
}
}
/* ---- helper: card with gradient + hover glow ---- */
function styleCard(id, rgb, idx) {
var el = document.getElementById(id);
if (!el) return;
var baseOp = 0.3 - idx * 0.05;
var gradOp = 0.04 - idx * 0.008;
el.style.setProperty(
"border-left",
"2px solid " + c(rgb, baseOp),
"important",
);
el.style.setProperty(
"background",
"linear-gradient(90deg, " + c(rgb, gradOp) + " 0%, transparent 70%)",
"important",
);
el.style.borderRadius = "0 4px 4px 0";
el.style.cursor = "pointer";
el.addEventListener("mouseenter", function () {
this.style.setProperty(
"background",
"linear-gradient(90deg, " +
c(rgb, 0.08) +
" 0%, " +
c(rgb, 0.02) +
" 60%, transparent 100%)",
"important",
);
this.style.setProperty("border-left-color", c(rgb, 0.6), "important");
this.style.setProperty(
"box-shadow",
"inset 3px 0 20px -4px " +
c(rgb, 0.15) +
", 0 0 25px " +
c(rgb, 0.04),
"important",
);
});
el.addEventListener("mouseleave", function () {
this.style.setProperty(
"background",
"linear-gradient(90deg, " + c(rgb, gradOp) + " 0%, transparent 70%)",
"important",
);
this.style.setProperty(
"border-left-color",
c(rgb, baseOp),
"important",
);
this.style.setProperty("box-shadow", "none", "important");
});
/* Make entire card area clickable */
var a = el.querySelector("a");
if (a) {
el.addEventListener("click", function (ev) {
var t = ev.target;
if (
t.tagName !== "A" &&
(!t.parentNode || t.parentNode.tagName !== "A")
) {
a.click();
}
});
}
}
}
/* Hook into multiple load events to guarantee we run AFTER Citizen skin */
if (typeof mw !== "undefined" && mw.hook) {
mw.hook("wikipage.content").add(run);
}
document.addEventListener("DOMContentLoaded", run);
window.addEventListener("load", function () {
setTimeout(run, 50);
});
})();
// Переключение вкладок и классов "chaos-*".
mw.hook("wikipage.content").add(function ($root) {
$root.find(".hj-chaos-container").each(function () {
var $container = $(this);
var $buttons = $container.find(".hj-chaos-tab-button");
var $blocks = $container.find(".hj-chaos-block");
if (!$buttons.length || !$blocks.length) return;
var CHAOS_CLASSES = "chaos-overview chaos-calm chaos-medium chaos-high";
function activate(key, $btn) {
// активная кнопка
$buttons.removeClass("active");
$btn.addClass("active");
// активный блок
$blocks.removeClass("active").hide();
$blocks
.filter('[data-chaos="' + key + '"]')
.addClass("active")
.show();
// класс на контейнере для раскраски рамок/фона
$container.removeClass(CHAOS_CLASSES).addClass("chaos-" + key);
}
// Инициализация
var $activeBtn = $buttons.filter(".active").first();
if ($activeBtn.length) {
activate($activeBtn.data("chaos"), $activeBtn);
} else {
var $first = $buttons.first();
activate($first.data("chaos"), $first);
}
// Клики
$buttons.off("click.hjChaos").on("click.hjChaos", function () {
var $btn = $(this);
activate($btn.data("chaos"), $btn);
});
});
});