MediaWiki:Common.js: различия между версиями
Mei Day (обсуждение | вклад) Нет описания правки |
Mei Day (обсуждение | вклад) Нет описания правки |
||
| Строка 148: | Строка 148: | ||
animate(); | animate(); | ||
})(); | |||
/* ---- Server online status ---- */ | |||
(function () { | |||
"use strict"; | |||
var el = document.getElementById("orb-online"); | |||
if (!el) return; | |||
// Uncomment and set STATUS_URL once you have a working endpoint: | |||
// var STATUS_URL = "https://your-domain.ru/api/server-status"; | |||
// fetch(STATUS_URL) | |||
// .then(function(r) { return r.json(); }) | |||
// .then(function(data) { | |||
// var count = data.players || 0; | |||
// el.textContent = count + "/100"; | |||
// el.style.color = count > 0 | |||
// ? "rgba(100,220,180,0.8)" | |||
// : "rgba(100,220,180,0.4)"; | |||
// }) | |||
// .catch(function() { | |||
// el.textContent = "offline"; | |||
// el.style.color = "rgba(255,100,100,0.5)"; | |||
// }); | |||
})(); | |||
/* ---- 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 sName = document.getElementById("orb-server-name"); | |||
if (sName) { | |||
sName.style.color = c(T, 0.8); | |||
sName.style.textShadow = "0 0 25px " + c(T, 0.2); | |||
} | |||
var onl = document.getElementById("orb-online"); | |||
if (onl) onl.style.color = c(T, 0.4); | |||
/* Server buttons */ | |||
var addr = document.getElementById("orb-addr"); | |||
if (addr) { | |||
addr.style.setProperty("border", "1px solid " + c(T, 0.2), "important"); | |||
addr.style.setProperty("border-radius", "4px", "important"); | |||
addr.style.setProperty("background", c(T, 0.05), "important"); | |||
addr.style.color = c(T, 0.65); | |||
} | |||
var btnIds = ["orb-btn-byond", "orb-btn-discord2"]; | |||
for (var k = 0; k < btnIds.length; k++) { | |||
var btn = document.getElementById(btnIds[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.55); | |||
el.style.textShadow = "0 0 20px " + c(rgb, 0.12); | |||
/* decorative underline bar */ | |||
if (!el.querySelector(".orb-ul")) { | |||
var ln = document.createElement("div"); | |||
ln.className = "orb-ul"; | |||
ln.style.cssText = | |||
"width:36px;height:1px;margin-top:8px;" + | |||
"background:" + | |||
c(rgb, 0.25) + | |||
";box-shadow:0 0 8px " + | |||
c(rgb, 0.08); | |||
el.appendChild(ln); | |||
} | |||
} | |||
/* ---- helper: card with hover glow ---- */ | |||
function styleCard(id, rgb, idx) { | |||
var el = document.getElementById(id); | |||
if (!el) return; | |||
var baseOp = 0.3 - idx * 0.05; | |||
el.style.setProperty( | |||
"border-left", | |||
"2px solid " + c(rgb, baseOp), | |||
"important" | |||
); | |||
el.style.borderRadius = "0 4px 4px 0"; | |||
el.style.cursor = "pointer"; | |||
el.addEventListener("mouseenter", function () { | |||
this.style.setProperty("background", c(rgb, 0.05), "important"); | |||
this.style.setProperty("border-left-color", c(rgb, 0.55), "important"); | |||
this.style.setProperty( | |||
"box-shadow", | |||
"inset 3px 0 15px -4px " + | |||
c(rgb, 0.12) + | |||
", 0 0 20px " + | |||
c(rgb, 0.03), | |||
"important" | |||
); | |||
}); | |||
el.addEventListener("mouseleave", function () { | |||
this.style.setProperty("background", "none", "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); | |||
}); | |||
})(); | })(); | ||
Версия от 13:27, 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 ---- */
(function () {
"use strict";
var el = document.getElementById("orb-online");
if (!el) return;
// Uncomment and set STATUS_URL once you have a working endpoint:
// var STATUS_URL = "https://your-domain.ru/api/server-status";
// fetch(STATUS_URL)
// .then(function(r) { return r.json(); })
// .then(function(data) {
// var count = data.players || 0;
// el.textContent = count + "/100";
// el.style.color = count > 0
// ? "rgba(100,220,180,0.8)"
// : "rgba(100,220,180,0.4)";
// })
// .catch(function() {
// el.textContent = "offline";
// el.style.color = "rgba(255,100,100,0.5)";
// });
})();
/* ---- 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 sName = document.getElementById("orb-server-name");
if (sName) {
sName.style.color = c(T, 0.8);
sName.style.textShadow = "0 0 25px " + c(T, 0.2);
}
var onl = document.getElementById("orb-online");
if (onl) onl.style.color = c(T, 0.4);
/* Server buttons */
var addr = document.getElementById("orb-addr");
if (addr) {
addr.style.setProperty("border", "1px solid " + c(T, 0.2), "important");
addr.style.setProperty("border-radius", "4px", "important");
addr.style.setProperty("background", c(T, 0.05), "important");
addr.style.color = c(T, 0.65);
}
var btnIds = ["orb-btn-byond", "orb-btn-discord2"];
for (var k = 0; k < btnIds.length; k++) {
var btn = document.getElementById(btnIds[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.55);
el.style.textShadow = "0 0 20px " + c(rgb, 0.12);
/* decorative underline bar */
if (!el.querySelector(".orb-ul")) {
var ln = document.createElement("div");
ln.className = "orb-ul";
ln.style.cssText =
"width:36px;height:1px;margin-top:8px;" +
"background:" +
c(rgb, 0.25) +
";box-shadow:0 0 8px " +
c(rgb, 0.08);
el.appendChild(ln);
}
}
/* ---- helper: card with hover glow ---- */
function styleCard(id, rgb, idx) {
var el = document.getElementById(id);
if (!el) return;
var baseOp = 0.3 - idx * 0.05;
el.style.setProperty(
"border-left",
"2px solid " + c(rgb, baseOp),
"important"
);
el.style.borderRadius = "0 4px 4px 0";
el.style.cursor = "pointer";
el.addEventListener("mouseenter", function () {
this.style.setProperty("background", c(rgb, 0.05), "important");
this.style.setProperty("border-left-color", c(rgb, 0.55), "important");
this.style.setProperty(
"box-shadow",
"inset 3px 0 15px -4px " +
c(rgb, 0.12) +
", 0 0 20px " +
c(rgb, 0.03),
"important"
);
});
el.addEventListener("mouseleave", function () {
this.style.setProperty("background", "none", "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);
});
});
});