MediaWiki:Common.js: Difference between revisions
Appearance
Fixed 3D tag cloud - pure JavaScript implementation, no external dependencies, guaranteed to work and auto-rotate |
Fixed 3D tag cloud initialization using mw.loader.using and mw.hook to ensure proper timing |
||
| Line 44: | Line 44: | ||
/** | /** | ||
* Simple 3D Rotating Tag Cloud - Pure JavaScript | * Simple 3D Rotating Tag Cloud - Pure JavaScript | ||
* | * Uses MediaWiki's module loader to ensure proper initialization | ||
*/ | */ | ||
(function() { | mw.loader.using(['mediawiki.util'], function() { | ||
// Only run on Main Page | // Only run on Main Page | ||
if (mw.config.get('wgPageName') !== 'Main_Page') { | if (mw.config.get('wgPageName') !== 'Main_Page') { | ||
| Line 53: | Line 53: | ||
} | } | ||
// Wait for DOM to be ready | |||
mw.hook('wikipage.content').add(function() { | |||
var canvas = document.getElementById('tagcanvas'); | var canvas = document.getElementById('tagcanvas'); | ||
if (!canvas) return; | if (!canvas) { | ||
console.log('Canvas element not found'); | |||
return; | |||
} | |||
console.log('Initializing 3D tag cloud...'); | |||
// Hide the fallback list | |||
var ul = canvas.querySelector('ul'); | |||
if (ul) { | |||
ul.style.display = 'none'; | |||
} | |||
var ctx = canvas.getContext('2d'); | var ctx = canvas.getContext('2d'); | ||
| Line 91: | Line 103: | ||
var lasta = 1; | var lasta = 1; | ||
var lastb = 1; | var lastb = 1; | ||
var tspeed = 0.5; | var tspeed = 0.5; | ||
var size = 250; | var size = 250; | ||
var mouseX = 0; | var mouseX = 0; | ||
var mouseY = 0; | var mouseY = 0; | ||
var active = false; | var active = false; | ||
// Build tag objects | |||
for (var i = 0; i < tags.length; i++) { | |||
var oTag = {}; | |||
for (i = 0; i < tags.length; i++) { | |||
oTag = {}; | |||
oTag.offsetWidth = tags[i].size * 5; | oTag.offsetWidth = tags[i].size * 5; | ||
oTag.offsetHeight = tags[i].size; | oTag.offsetHeight = tags[i].size; | ||
| Line 110: | Line 117: | ||
oTag.url = tags[i].url; | oTag.url = tags[i].url; | ||
oTag.size = tags[i].size; | oTag.size = tags[i].size; | ||
mcList.push(oTag); | mcList.push(oTag); | ||
} | } | ||
var sa, ca, sb, cb, sc, cc; | |||
function sineCosine(a, b, c) { | |||
sa = Math.sin(a * dtr); | |||
ca = Math.cos(a * dtr); | |||
sb = Math.sin(b * dtr); | |||
cb = Math.cos(b * dtr); | |||
sc = Math.sin(c * dtr); | |||
cc = Math.cos(c * dtr); | |||
} | |||
function positionAll() { | |||
var phi = 0; | |||
var theta = 0; | |||
var max = mcList.length; | |||
for (var i = 0; i < max; i++) { | |||
phi = Math.acos(-1 + (2 * i + 1) / max); | |||
theta = Math.sqrt(max * Math.PI) * phi; | |||
mcList[i].cx = radius * Math.cos(theta) * Math.sin(phi); | |||
mcList[i].cy = radius * Math.sin(theta) * Math.sin(phi); | |||
mcList[i].cz = radius * Math.cos(phi); | |||
} | |||
} | } | ||
function doPosition() { | |||
ctx.clearRect(0, 0, width, height); | |||
for (var i = 0; i < mcList.length; i++) { | for (var i = 0; i < mcList.length; i++) { | ||
var tag = mcList[i]; | var tag = mcList[i]; | ||
var | var x = tag.x + width / 2; | ||
var | var y = tag.y + height / 2; | ||
var | |||
var alpha = Math.max(0.2, Math.min(1, tag.alpha)); | |||
var fontSize = Math.max(10, tag.size * tag.scale); | |||
ctx.save(); | |||
ctx.font = fontSize + 'px sans-serif'; | |||
ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')'; | |||
ctx.textAlign = 'center'; | |||
ctx.textBaseline = 'middle'; | |||
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'; | |||
ctx.shadowBlur = 4; | |||
ctx.shadowOffsetX = 0; | |||
ctx.shadowOffsetY = 2; | |||
ctx.fillText(tag.text, x, y); | |||
ctx.restore(); | |||
tag.cx = x; | |||
tag.cy = y; | |||
} | } | ||
} | } | ||
function depthSort() { | |||
mcList.sort(function(a, b) { | |||
return (b.cz - a.cz); | |||
}); | |||
} | |||
function update() { | function update() { | ||
var a | var a, b; | ||
if (active) { | if (active) { | ||
| Line 204: | Line 231: | ||
} | } | ||
// Event handlers | |||
canvas.onmouseover = function() { | |||
active = true; | |||
}; | |||
} | |||
function | canvas.onmouseout = function() { | ||
active = false; | |||
}; | |||
var | canvas.onmousemove = function(ev) { | ||
var rect = canvas.getBoundingClientRect(); | |||
mouseX = ev.clientX - rect.left - width / 2; | |||
mouseY = ev.clientY - rect.top - height / 2; | |||
}; | |||
canvas.onclick = function(ev) { | |||
var rect = canvas.getBoundingClientRect(); | |||
var mx = ev.clientX - rect.left; | |||
var my = ev.clientY - rect.top; | |||
for (var i = 0; i < mcList.length; i++) { | for (var i = 0; i < mcList.length; i++) { | ||
var tag = mcList[i]; | var tag = mcList[i]; | ||
var | var dx = mx - tag.cx; | ||
var | var dy = my - tag.cy; | ||
var dist = Math.sqrt(dx * dx + dy * dy); | |||
if (dist < 50) { | |||
window.location.href = tag.url; | |||
break; | |||
} | |||
} | } | ||
} | }; | ||
canvas.style.cursor = 'pointer'; | |||
// Initialize | |||
sineCosine(0, 0, 0); | |||
positionAll(); | |||
setInterval(update, 30); | |||
console.log('3D tag cloud initialized successfully'); | |||
}); | }); | ||
} | }); | ||
Revision as of 10:40, 20 October 2025
/**
* Add statistics banner to account creation page
*/
(function() {
// Only run on Special:CreateAccount page
if (mw.config.get('wgCanonicalSpecialPageName') !== 'CreateAccount') {
return;
}
// Get site statistics via API
var api = new mw.Api();
api.get({
action: 'query',
meta: 'siteinfo',
siprop: 'statistics',
format: 'json'
}).done(function(data) {
var stats = data.query.statistics;
// Create statistics banner
var banner = $('<div>').addClass('createaccount-statistics').html(
'<div class="createaccount-statistics-title">CEO.wiki is made by people like you.</div>' +
'<div class="createaccount-statistics-grid">' +
'<div class="createaccount-stat-item">' +
'<div class="createaccount-stat-number">' + stats.edits.toLocaleString() + '</div>' +
'<div class="createaccount-stat-label">Edits</div>' +
'</div>' +
'<div class="createaccount-stat-item">' +
'<div class="createaccount-stat-number">' + stats.pages.toLocaleString() + '</div>' +
'<div class="createaccount-stat-label">Pages</div>' +
'</div>' +
'<div class="createaccount-stat-item">' +
'<div class="createaccount-stat-number">' + stats.activeusers.toLocaleString() + '</div>' +
'<div class="createaccount-stat-label">Recent Contributors</div>' +
'</div>' +
'</div>'
);
// Insert banner before the form
$('#userloginForm').before(banner);
});
})();
/**
* Simple 3D Rotating Tag Cloud - Pure JavaScript
* Uses MediaWiki's module loader to ensure proper initialization
*/
mw.loader.using(['mediawiki.util'], function() {
// Only run on Main Page
if (mw.config.get('wgPageName') !== 'Main_Page') {
return;
}
// Wait for DOM to be ready
mw.hook('wikipage.content').add(function() {
var canvas = document.getElementById('tagcanvas');
if (!canvas) {
console.log('Canvas element not found');
return;
}
console.log('Initializing 3D tag cloud...');
// Hide the fallback list
var ul = canvas.querySelector('ul');
if (ul) {
ul.style.display = 'none';
}
var ctx = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
// Tags configuration
var tags = [
{ text: 'Satya Nadella', url: '/wiki/Satya_Nadella', size: 24 },
{ text: 'Tim Cook', url: '/wiki/Tim_Cook', size: 22 },
{ text: 'Elon Musk', url: '/wiki/Elon_Musk', size: 26 },
{ text: 'Mark Zuckerberg', url: '/wiki/Mark_Zuckerberg', size: 20 },
{ text: 'Sundar Pichai', url: '/wiki/Sundar_Pichai', size: 20 },
{ text: 'Andy Jassy', url: '/wiki/Andy_Jassy', size: 18 },
{ text: 'Jensen Huang', url: '/wiki/Jensen_Huang', size: 22 },
{ text: 'Lisa Su', url: '/wiki/Lisa_Su', size: 18 },
{ text: 'Mary Barra', url: '/wiki/Mary_Barra', size: 18 },
{ text: 'Jamie Dimon', url: '/wiki/Jamie_Dimon', size: 18 },
{ text: 'Microsoft', url: '/wiki/Microsoft', size: 16 },
{ text: 'Apple', url: '/wiki/Apple_Inc.', size: 16 },
{ text: 'Amazon', url: '/wiki/Amazon', size: 16 },
{ text: 'Google', url: '/wiki/Google', size: 16 },
{ text: 'Tesla', url: '/wiki/Tesla', size: 16 },
{ text: 'Leadership', url: '/wiki/Category:Chief_executive_officers', size: 14 },
{ text: 'Innovation', url: '/wiki/Category:Business_strategies', size: 14 },
{ text: 'Technology', url: '/wiki/Category:Companies', size: 14 },
{ text: 'Strategy', url: '/wiki/Category:Business_strategies', size: 14 },
{ text: 'Cloud Computing', url: '/wiki/Category:Industry_analysis', size: 14 }
];
// Initialize 3D positions
var radius = 180;
var dtr = Math.PI / 180;
var mcList = [];
var lasta = 1;
var lastb = 1;
var tspeed = 0.5;
var size = 250;
var mouseX = 0;
var mouseY = 0;
var active = false;
// Build tag objects
for (var i = 0; i < tags.length; i++) {
var oTag = {};
oTag.offsetWidth = tags[i].size * 5;
oTag.offsetHeight = tags[i].size;
oTag.text = tags[i].text;
oTag.url = tags[i].url;
oTag.size = tags[i].size;
mcList.push(oTag);
}
var sa, ca, sb, cb, sc, cc;
function sineCosine(a, b, c) {
sa = Math.sin(a * dtr);
ca = Math.cos(a * dtr);
sb = Math.sin(b * dtr);
cb = Math.cos(b * dtr);
sc = Math.sin(c * dtr);
cc = Math.cos(c * dtr);
}
function positionAll() {
var phi = 0;
var theta = 0;
var max = mcList.length;
for (var i = 0; i < max; i++) {
phi = Math.acos(-1 + (2 * i + 1) / max);
theta = Math.sqrt(max * Math.PI) * phi;
mcList[i].cx = radius * Math.cos(theta) * Math.sin(phi);
mcList[i].cy = radius * Math.sin(theta) * Math.sin(phi);
mcList[i].cz = radius * Math.cos(phi);
}
}
function doPosition() {
ctx.clearRect(0, 0, width, height);
for (var i = 0; i < mcList.length; i++) {
var tag = mcList[i];
var x = tag.x + width / 2;
var y = tag.y + height / 2;
var alpha = Math.max(0.2, Math.min(1, tag.alpha));
var fontSize = Math.max(10, tag.size * tag.scale);
ctx.save();
ctx.font = fontSize + 'px sans-serif';
ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 4;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 2;
ctx.fillText(tag.text, x, y);
ctx.restore();
tag.cx = x;
tag.cy = y;
}
}
function depthSort() {
mcList.sort(function(a, b) {
return (b.cz - a.cz);
});
}
function update() {
var a, b;
if (active) {
a = (-Math.min(Math.max(-mouseY, -size), size) / radius) * tspeed;
b = (Math.min(Math.max(-mouseX, -size), size) / radius) * tspeed;
} else {
a = lasta * 0.98;
b = lastb * 0.98 + 0.01;
}
lasta = a;
lastb = b;
if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01) {
return;
}
var c = 0;
sineCosine(a, b, c);
for (var i = 0; i < mcList.length; i++) {
var rx1 = mcList[i].cx;
var ry1 = mcList[i].cy * ca + mcList[i].cz * (-sa);
var rz1 = mcList[i].cy * sa + mcList[i].cz * ca;
var rx2 = rx1 * cb + rz1 * sb;
var ry2 = ry1;
var rz2 = rx1 * (-sb) + rz1 * cb;
var rx3 = rx2 * cc + ry2 * (-sc);
var ry3 = rx2 * sc + ry2 * cc;
var rz3 = rz2;
mcList[i].cx = rx3;
mcList[i].cy = ry3;
mcList[i].cz = rz3;
var per = size / (size + rz3);
mcList[i].x = rx3 * per;
mcList[i].y = ry3 * per;
mcList[i].scale = per;
mcList[i].alpha = per;
mcList[i].alpha = (mcList[i].alpha - 0.6) * (10 / 6);
}
doPosition();
depthSort();
}
// Event handlers
canvas.onmouseover = function() {
active = true;
};
canvas.onmouseout = function() {
active = false;
};
canvas.onmousemove = function(ev) {
var rect = canvas.getBoundingClientRect();
mouseX = ev.clientX - rect.left - width / 2;
mouseY = ev.clientY - rect.top - height / 2;
};
canvas.onclick = function(ev) {
var rect = canvas.getBoundingClientRect();
var mx = ev.clientX - rect.left;
var my = ev.clientY - rect.top;
for (var i = 0; i < mcList.length; i++) {
var tag = mcList[i];
var dx = mx - tag.cx;
var dy = my - tag.cy;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 50) {
window.location.href = tag.url;
break;
}
}
};
canvas.style.cursor = 'pointer';
// Initialize
sineCosine(0, 0, 0);
positionAll();
setInterval(update, 30);
console.log('3D tag cloud initialized successfully');
});
});