MediaWiki:Common.js: Difference between revisions
Appearance
Replaced with stylish weighted tag cloud - larger fonts for popular items, gradient colors, floating animations |
Replaced with true 3D rotating sphere tag cloud - continuously spinning with size-based visibility |
||
| Line 1: | Line 1: | ||
/* | /* 3D Rotating Tag Cloud Sphere */ | ||
(function() { | (function() { | ||
if (typeof window.CEOTagCloudInit !== 'undefined') return; | if (typeof window.CEOTagCloudInit !== 'undefined') return; | ||
window.CEOTagCloudInit = true; | window.CEOTagCloudInit = true; | ||
function | function build3DTagCloud() { | ||
var placeholder = document.getElementById('ceo-tagcloud-placeholder'); | var placeholder = document.getElementById('ceo-tagcloud-placeholder'); | ||
if (!placeholder) return; | if (!placeholder) return; | ||
// Tag data | // Tag data - weight determines size | ||
var tags = [ | var tags = [ | ||
{text: 'Satya Nadella', href: '/wiki/Satya_Nadella', weight: 10}, | {text: 'Satya Nadella', href: '/wiki/Satya_Nadella', weight: 10}, | ||
| Line 16: | Line 16: | ||
{text: 'Mary Barra', href: '/wiki/Mary_Barra', weight: 8}, | {text: 'Mary Barra', href: '/wiki/Mary_Barra', weight: 8}, | ||
{text: 'Apple', href: '/wiki/Apple_Inc.', weight: 8}, | {text: 'Apple', href: '/wiki/Apple_Inc.', weight: 8}, | ||
{text: 'Microsoft', href: '/wiki/Microsoft', weight: 7}, | {text: 'Microsoft', href: '/wiki/Microsoft', weight: 7}, | ||
{text: 'Google', href: '/wiki/Google', weight: 7}, | |||
{text: 'Amazon', href: '/wiki/Amazon', weight: 7}, | {text: 'Amazon', href: '/wiki/Amazon', weight: 7}, | ||
{text: ' | {text: 'Tech CEOs', href: '/wiki/Category:Technology_CEOs', weight: 6}, | ||
{text: 'CEO Profiles', href: '/wiki/Category:Chief_executive_officers', weight: | {text: 'CEO Profiles', href: '/wiki/Category:Chief_executive_officers', weight: 6}, | ||
{text: 'Companies', href: '/wiki/Category:Companies', weight: | {text: 'Companies', href: '/wiki/Category:Companies', weight: 5}, | ||
{text: ' | {text: 'Fortune 500', href: '/wiki/Category:Fortune_500_CEOs', weight: 5}, | ||
{text: 'CEOs | {text: 'American CEOs', href: '/wiki/Category:American_CEOs', weight: 5}, | ||
{text: ' | {text: 'General Motors', href: '/wiki/General_Motors', weight: 4}, | ||
{text: ' | {text: 'CEOs by Country', href: '/wiki/Category:CEOs_by_country', weight: 4}, | ||
{text: ' | {text: 'Business Strategy', href: '/wiki/Category:Business_strategies', weight: 4}, | ||
{text: ' | {text: 'Governance', href: '/wiki/Category:Corporate_governance', weight: 3}, | ||
{text: ' | {text: 'Industry Analysis', href: '/wiki/Category:Industry_analysis', weight: 3}, | ||
{text: 'Random', href: '/wiki/Special:Random', weight: 3} | |||
{ | |||
]; | ]; | ||
var cloudHTML = '<div class="mp-card" style="margin-top: 1em;">' + | var cloudHTML = '<div class="mp-card" style="margin-top: 1em;">' + | ||
'<div class="mp-card-title"> | '<div class="mp-card-title">Popular Topics</div>' + | ||
'<div class="mp-card-content" style="padding: | '<div class="mp-card-content" style="padding: 1.5em;">' + | ||
'<div | '<div id="tag-cloud-3d" style="width: 100%; height: 400px; position: relative; perspective: 600px; background: radial-gradient(circle at center, #667eea 0%, #764ba2 100%); border-radius: 12px; overflow: hidden;">' + | ||
'<div id="tag-sphere" style="position: absolute; width: 100%; height: 100%; transform-style: preserve-3d;"></div>' + | |||
'<div style=" | |||
'</div>' + | '</div>' + | ||
'<div style="text-align: center; margin-top: 1em; font-size: 0.8em; color: #6b7280;">Hover to control • Larger = More popular</div>' + | |||
'</div></div>'; | '</div></div>'; | ||
placeholder.innerHTML = cloudHTML; | placeholder.innerHTML = cloudHTML; | ||
var cloudContainer = document.getElementById(' | var container = document.getElementById('tag-sphere'); | ||
if (! | var cloudContainer = document.getElementById('tag-cloud-3d'); | ||
if (!container) return; | |||
// Create | var radius = 160; | ||
tags.forEach(function(tag | var dtr = Math.PI / 180; | ||
var items = []; | |||
var active = false; | |||
var lasta = 1; | |||
var lastb = 1; | |||
var mouseX = 0; | |||
var mouseY = 0; | |||
var tspeed = 3; | |||
// Create tags | |||
tags.forEach(function(tag) { | |||
var a = document.createElement('a'); | var a = document.createElement('a'); | ||
a.href = tag.href; | a.href = tag.href; | ||
a.textContent = tag.text; | a.textContent = tag.text; | ||
a. | a.style.position = 'absolute'; | ||
a.style.left = '0px'; | |||
a.style.top = '0px'; | |||
a.style.color = '#ffffff'; | |||
a.style.textDecoration = 'none'; | |||
a.style.padding = '0.3em 0.7em'; | |||
a.style.whiteSpace = 'nowrap'; | |||
a.style.fontWeight = '700'; | |||
a.style.textShadow = '0 2px 8px rgba(0,0,0,0.4)'; | |||
a.style.transition = 'all 0.3s ease'; | |||
a.style.borderRadius = '20px'; | |||
a.style.background = 'rgba(255, 255, 255, 0.15)'; | |||
a.style.backdropFilter = 'blur(10px)'; | |||
// Font size based on weight ( | // Font size based on weight (1em to 2.5em) | ||
var fontSize = 0.8 + (tag.weight / 10) * 1.7; | var fontSize = 0.8 + (tag.weight / 10) * 1.7; | ||
a.style.fontSize = fontSize + 'em'; | a.style.fontSize = fontSize + 'em'; | ||
a.addEventListener('mouseenter', function() { | |||
this.style.background = 'rgba(255, 255, 255, 0.95)'; | |||
this.style.color = '#667eea'; | |||
this.style.transform = 'scale(1.2)'; | |||
this.style.zIndex = '1000'; | |||
}); | |||
a.addEventListener('mouseleave', function() { | |||
this.style.background = 'rgba(255, 255, 255, 0.15)'; | |||
this.style.color = '#ffffff'; | |||
this.style.transform = 'scale(1)'; | |||
this.style.zIndex = 'auto'; | |||
}); | |||
container.appendChild(a); | |||
var item = { | |||
element: a, | |||
cx: 0, | |||
cy: 0, | |||
cz: 0, | |||
h: a.offsetHeight, | |||
w: a.offsetWidth | |||
}; | |||
items.push(item); | |||
}); | }); | ||
// | // Position items on sphere | ||
var | positionAll(); | ||
function positionAll() { | |||
var phi = 0; | |||
var theta = 0; | |||
var max = items.length; | |||
}); | for (var i = 0; i < max; i++) { | ||
phi = Math.acos(-1 + (2 * i + 1) / max); | |||
theta = Math.sqrt(max * Math.PI) * phi; | |||
items[i].cx = radius * Math.cos(theta) * Math.sin(phi); | |||
items[i].cy = radius * Math.sin(theta) * Math.sin(phi); | |||
items[i].cz = radius * Math.cos(phi); | |||
} | |||
} | |||
// Rotation math | |||
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); | |||
} | |||
// Main animation loop | |||
function update() { | |||
var a, b; | |||
if (active) { | |||
var rect = cloudContainer.getBoundingClientRect(); | |||
a = (-Math.min(Math.max(-mouseY, -200), 200) / radius) * tspeed; | |||
b = (Math.min(Math.max(-mouseX, -200), 200) / radius) * tspeed; | |||
} else { | |||
a = lasta * 0.98; | |||
b = lastb * 0.98; | |||
} | |||
lasta = a; | |||
lastb = b; | |||
// Continuous rotation when idle | |||
if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01 && !active) { | |||
a = 0.5; | |||
b = 0.5; | |||
} | |||
var c = 0; | |||
sineCosine(a, b, c); | |||
for (var i = 0; i < items.length; i++) { | |||
var item = items[i]; | |||
// Rotate around X axis | |||
var rx1 = item.cx; | |||
var ry1 = item.cy * ca + item.cz * (-sa); | |||
var rz1 = item.cy * sa + item.cz * ca; | |||
} | // Rotate around Y axis | ||
var rx2 = rx1 * cb + rz1 * sb; | |||
var ry2 = ry1; | |||
var rz2 = rx1 * (-sb) + rz1 * cb; | |||
// Rotate around Z axis | |||
var rx3 = rx2 * cc + ry2 * (-sc); | |||
var ry3 = rx2 * sc + ry2 * cc; | |||
var rz3 = rz2; | |||
item.cx = rx3; | |||
item.cy = ry3; | |||
item.cz = rz3; | |||
// Perspective calculation | |||
var per = 500 / (500 + rz3); | |||
var x = rx3 * per; | |||
var y = ry3 * per; | |||
// Position element | |||
var l = (cloudContainer.offsetWidth / 2) + x - (item.w / 2); | |||
var t = (cloudContainer.offsetHeight / 2) + y - (item.h / 2); | |||
item.element.style.left = l + 'px'; | |||
item.element.style.top = t + 'px'; | |||
// Opacity based on depth | |||
var alpha = (per - 0.5) * 2; | |||
alpha = Math.max(0.3, Math.min(1, alpha)); | |||
item.element.style.opacity = alpha; | |||
// Z-index based on depth | |||
item.element.style.zIndex = Math.floor(per * 100); | |||
} | |||
} | } | ||
// Mouse interaction | |||
cloudContainer.addEventListener('mouseenter', function() { | |||
active = true; | |||
}); | |||
cloudContainer.addEventListener('mouseleave', function() { | |||
active = false; | |||
}); | |||
cloudContainer.addEventListener('mousemove', function(e) { | |||
var rect = this.getBoundingClientRect(); | |||
mouseX = e.clientX - rect.left - (this.offsetWidth / 2); | |||
mouseY = e.clientY - rect.top - (this.offsetHeight / 2); | |||
}); | |||
// Start animation | |||
setInterval(update, 30); | |||
} | } | ||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
document.addEventListener('DOMContentLoaded', | document.addEventListener('DOMContentLoaded', build3DTagCloud); | ||
} else { | } else { | ||
build3DTagCloud(); | |||
} | } | ||
})(); | })(); | ||
Revision as of 12:20, 19 October 2025
/* 3D Rotating Tag Cloud Sphere */
(function() {
if (typeof window.CEOTagCloudInit !== 'undefined') return;
window.CEOTagCloudInit = true;
function build3DTagCloud() {
var placeholder = document.getElementById('ceo-tagcloud-placeholder');
if (!placeholder) return;
// Tag data - weight determines size
var tags = [
{text: 'Satya Nadella', href: '/wiki/Satya_Nadella', weight: 10},
{text: 'Sundar Pichai', href: '/wiki/Sundar_Pichai', weight: 10},
{text: 'Tim Cook', href: '/wiki/Tim_Cook', weight: 9},
{text: 'Andy Jassy', href: '/wiki/Andy_Jassy', weight: 9},
{text: 'Mary Barra', href: '/wiki/Mary_Barra', weight: 8},
{text: 'Apple', href: '/wiki/Apple_Inc.', weight: 8},
{text: 'Microsoft', href: '/wiki/Microsoft', weight: 7},
{text: 'Google', href: '/wiki/Google', weight: 7},
{text: 'Amazon', href: '/wiki/Amazon', weight: 7},
{text: 'Tech CEOs', href: '/wiki/Category:Technology_CEOs', weight: 6},
{text: 'CEO Profiles', href: '/wiki/Category:Chief_executive_officers', weight: 6},
{text: 'Companies', href: '/wiki/Category:Companies', weight: 5},
{text: 'Fortune 500', href: '/wiki/Category:Fortune_500_CEOs', weight: 5},
{text: 'American CEOs', href: '/wiki/Category:American_CEOs', weight: 5},
{text: 'General Motors', href: '/wiki/General_Motors', weight: 4},
{text: 'CEOs by Country', href: '/wiki/Category:CEOs_by_country', weight: 4},
{text: 'Business Strategy', href: '/wiki/Category:Business_strategies', weight: 4},
{text: 'Governance', href: '/wiki/Category:Corporate_governance', weight: 3},
{text: 'Industry Analysis', href: '/wiki/Category:Industry_analysis', weight: 3},
{text: 'Random', href: '/wiki/Special:Random', weight: 3}
];
var cloudHTML = '<div class="mp-card" style="margin-top: 1em;">' +
'<div class="mp-card-title">Popular Topics</div>' +
'<div class="mp-card-content" style="padding: 1.5em;">' +
'<div id="tag-cloud-3d" style="width: 100%; height: 400px; position: relative; perspective: 600px; background: radial-gradient(circle at center, #667eea 0%, #764ba2 100%); border-radius: 12px; overflow: hidden;">' +
'<div id="tag-sphere" style="position: absolute; width: 100%; height: 100%; transform-style: preserve-3d;"></div>' +
'</div>' +
'<div style="text-align: center; margin-top: 1em; font-size: 0.8em; color: #6b7280;">Hover to control • Larger = More popular</div>' +
'</div></div>';
placeholder.innerHTML = cloudHTML;
var container = document.getElementById('tag-sphere');
var cloudContainer = document.getElementById('tag-cloud-3d');
if (!container) return;
var radius = 160;
var dtr = Math.PI / 180;
var items = [];
var active = false;
var lasta = 1;
var lastb = 1;
var mouseX = 0;
var mouseY = 0;
var tspeed = 3;
// Create tags
tags.forEach(function(tag) {
var a = document.createElement('a');
a.href = tag.href;
a.textContent = tag.text;
a.style.position = 'absolute';
a.style.left = '0px';
a.style.top = '0px';
a.style.color = '#ffffff';
a.style.textDecoration = 'none';
a.style.padding = '0.3em 0.7em';
a.style.whiteSpace = 'nowrap';
a.style.fontWeight = '700';
a.style.textShadow = '0 2px 8px rgba(0,0,0,0.4)';
a.style.transition = 'all 0.3s ease';
a.style.borderRadius = '20px';
a.style.background = 'rgba(255, 255, 255, 0.15)';
a.style.backdropFilter = 'blur(10px)';
// Font size based on weight (1em to 2.5em)
var fontSize = 0.8 + (tag.weight / 10) * 1.7;
a.style.fontSize = fontSize + 'em';
a.addEventListener('mouseenter', function() {
this.style.background = 'rgba(255, 255, 255, 0.95)';
this.style.color = '#667eea';
this.style.transform = 'scale(1.2)';
this.style.zIndex = '1000';
});
a.addEventListener('mouseleave', function() {
this.style.background = 'rgba(255, 255, 255, 0.15)';
this.style.color = '#ffffff';
this.style.transform = 'scale(1)';
this.style.zIndex = 'auto';
});
container.appendChild(a);
var item = {
element: a,
cx: 0,
cy: 0,
cz: 0,
h: a.offsetHeight,
w: a.offsetWidth
};
items.push(item);
});
// Position items on sphere
positionAll();
function positionAll() {
var phi = 0;
var theta = 0;
var max = items.length;
for (var i = 0; i < max; i++) {
phi = Math.acos(-1 + (2 * i + 1) / max);
theta = Math.sqrt(max * Math.PI) * phi;
items[i].cx = radius * Math.cos(theta) * Math.sin(phi);
items[i].cy = radius * Math.sin(theta) * Math.sin(phi);
items[i].cz = radius * Math.cos(phi);
}
}
// Rotation math
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);
}
// Main animation loop
function update() {
var a, b;
if (active) {
var rect = cloudContainer.getBoundingClientRect();
a = (-Math.min(Math.max(-mouseY, -200), 200) / radius) * tspeed;
b = (Math.min(Math.max(-mouseX, -200), 200) / radius) * tspeed;
} else {
a = lasta * 0.98;
b = lastb * 0.98;
}
lasta = a;
lastb = b;
// Continuous rotation when idle
if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01 && !active) {
a = 0.5;
b = 0.5;
}
var c = 0;
sineCosine(a, b, c);
for (var i = 0; i < items.length; i++) {
var item = items[i];
// Rotate around X axis
var rx1 = item.cx;
var ry1 = item.cy * ca + item.cz * (-sa);
var rz1 = item.cy * sa + item.cz * ca;
// Rotate around Y axis
var rx2 = rx1 * cb + rz1 * sb;
var ry2 = ry1;
var rz2 = rx1 * (-sb) + rz1 * cb;
// Rotate around Z axis
var rx3 = rx2 * cc + ry2 * (-sc);
var ry3 = rx2 * sc + ry2 * cc;
var rz3 = rz2;
item.cx = rx3;
item.cy = ry3;
item.cz = rz3;
// Perspective calculation
var per = 500 / (500 + rz3);
var x = rx3 * per;
var y = ry3 * per;
// Position element
var l = (cloudContainer.offsetWidth / 2) + x - (item.w / 2);
var t = (cloudContainer.offsetHeight / 2) + y - (item.h / 2);
item.element.style.left = l + 'px';
item.element.style.top = t + 'px';
// Opacity based on depth
var alpha = (per - 0.5) * 2;
alpha = Math.max(0.3, Math.min(1, alpha));
item.element.style.opacity = alpha;
// Z-index based on depth
item.element.style.zIndex = Math.floor(per * 100);
}
}
// Mouse interaction
cloudContainer.addEventListener('mouseenter', function() {
active = true;
});
cloudContainer.addEventListener('mouseleave', function() {
active = false;
});
cloudContainer.addEventListener('mousemove', function(e) {
var rect = this.getBoundingClientRect();
mouseX = e.clientX - rect.left - (this.offsetWidth / 2);
mouseY = e.clientY - rect.top - (this.offsetHeight / 2);
});
// Start animation
setInterval(update, 30);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', build3DTagCloud);
} else {
build3DTagCloud();
}
})();