MediaWiki:Common.js: различия между версиями
Mei Day (обсуждение | вклад) Нет описания правки |
Mei Day (обсуждение | вклад) Нет описания правки |
||
| Строка 16: | Строка 16: | ||
var starsSmallEl = document.getElementById("parallax-stars-small"); | var starsSmallEl = document.getElementById("parallax-stars-small"); | ||
var starsBigEl = document.getElementById("parallax-stars-big"); | var starsBigEl = document.getElementById("parallax-stars-big"); | ||
// Disable parallax on diff/comparison pages so it doesn't cover the diff view | |||
if ((new URLSearchParams(window.location.search)).has("diff")) { | |||
var hideEls = [parallaxBg, nebulaEl, starsSmallEl, starsBigEl, | |||
document.getElementById("orbitalis-vignette")]; | |||
for (var h = 0; h < hideEls.length; h++) { | |||
if (hideEls[h]) hideEls[h].style.display = "none"; | |||
} | |||
// Restore default content background so diff table is readable | |||
var contentEl = document.getElementById("content"); | |||
if (contentEl) { | |||
contentEl.style.background = "#14141a"; | |||
} | |||
return; | |||
} | |||
// ---- Apply styles to the parallax elements ---------------------------- | // ---- Apply styles to the parallax elements ---------------------------- | ||
Версия от 15:41, 10 марта 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");
// Disable parallax on diff/comparison pages so it doesn't cover the diff view
if ((new URLSearchParams(window.location.search)).has("diff")) {
var hideEls = [parallaxBg, nebulaEl, starsSmallEl, starsBigEl,
document.getElementById("orbitalis-vignette")];
for (var h = 0; h < hideEls.length; h++) {
if (hideEls[h]) hideEls[h].style.display = "none";
}
// Restore default content background so diff table is readable
var contentEl = document.getElementById("content");
if (contentEl) {
contentEl.style.background = "#14141a";
}
return;
}
// ---- 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 + info ---- */
/* Queries /api/status.php on the same wiki host — which sends a UDP BYOND
* topic to localhost:41060 and returns JSON { players, map_name, chaos_level, ... }.
* No proxy needed: wiki and game server share the same machine.
*/
(function () {
"use strict";
var elOnline = document.getElementById("orb-online");
var elMap = document.getElementById("orb-map-val");
var elST = document.getElementById("orb-st-val");
if (!elOnline) return;
var STATUS_URL = "/api/status.json";
var REFRESH_MS = 30000;
function update() {
fetch(STATUS_URL)
.then(function (r) {
console.log("[Orbitalis Status] HTTP", r.status, r.url);
if (!r.ok) throw new Error("HTTP " + r.status);
return r.json();
})
.then(function (data) {
console.log("[Orbitalis Status] Data:", data);
var count = parseInt(data.players, 10);
if (isNaN(count)) throw new Error("bad data: players=" + data.players);
elOnline.textContent = count + " онлайн";
elOnline.style.color =
count > 0
? "rgba(100,220,180,0.75)"
: "rgba(100,220,180,0.35)";
elOnline.style.textShadow =
count > 0
? "0 0 15px rgba(100,220,180,0.2)"
: "none";
if (elMap && data.map_name) {
elMap.textContent = data.map_name;
elMap.style.color = "rgba(255,255,255,0.55)";
}
if (elST && data.chaos_level) {
elST.textContent = data.chaos_level;
elST.style.color = "rgba(255,255,255,0.55)";
}
})
.catch(function (err) {
console.error("[Orbitalis Status] Fetch failed:", err);
elOnline.textContent = "оффлайн";
elOnline.style.color = "rgba(255,120,120,0.5)";
elOnline.style.textShadow = "none";
if (elMap) elMap.textContent = "—";
if (elST) elST.textContent = "—";
});
}
update();
setInterval(update, REFRESH_MS);
})();
/* ---- Main page: interactive engine ---- */
/* All visual styling is in Common.css (CSS-first approach).
JS handles: nuclear strip for <a> tags, click handlers.
Safe to re-run on Citizen DOM updates. */
(function () {
"use strict";
function run() {
var orb = document.getElementById("orb-content");
if (!orb) return;
/* Nuclear strip: clear Citizen-applied backgrounds on <a> tags only */
var links = orb.querySelectorAll("a");
for (var i = 0; i < links.length; i++) {
var a = links[i];
a.style.setProperty("background", "none", "important");
a.style.setProperty("background-color", "transparent", "important");
a.style.setProperty("background-image", "none", "important");
a.style.setProperty("box-shadow", "none", "important");
a.style.setProperty("border", "none", "important");
a.style.setProperty("padding", "0", "important");
a.style.setProperty("text-decoration", "none", "important");
}
/* Connect button — byond:// link */
var addr = document.getElementById("orb-addr");
if (addr && !addr._orbClick) {
addr._orbClick = true;
addr.addEventListener("click", function () {
window.location.href = "byond://45.141.208.222:41060";
});
}
/* Make entire card area clickable */
var cardIds = [
"orb-card-1", "orb-card-2", "orb-card-3", "orb-card-4",
"orb-card-5", "orb-card-6", "orb-card-7", "orb-card-8"
];
for (var j = 0; j < cardIds.length; j++) {
var card = document.getElementById(cardIds[j]);
if (card && !card._orbClick) {
card._orbClick = true;
(function (c) {
var link = c.querySelector("a");
if (link) {
c.addEventListener("click", function (ev) {
if (ev.target.tagName !== "A" &&
(!ev.target.parentNode || ev.target.parentNode.tagName !== "A")) {
link.click();
}
});
}
})(card);
}
}
}
/* Hook into multiple events — retry for Citizen's late DOM updates */
if (typeof mw !== "undefined" && mw.hook) {
mw.hook("wikipage.content").add(run);
}
document.addEventListener("DOMContentLoaded", run);
window.addEventListener("load", function () {
setTimeout(run, 50);
setTimeout(run, 500);
});
})();
// Переключение вкладок и классов "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);
});
});
});