MediaWiki:Common.js: Difference between revisions
Appearance
Added 3D interactive tag cloud JavaScript for Main Page |
Updated to dynamically build 3D tag cloud from placeholder |
||
| Line 1: | Line 1: | ||
/* 3D Tag Cloud | /* 3D Tag Cloud - Dynamic Builder */ | ||
(function() { | (function() { | ||
if (typeof window. | if (typeof window.CEOTagCloudInit !== 'undefined') return; | ||
window. | window.CEOTagCloudInit = true; | ||
function | function buildAndInitTagCloud() { | ||
var placeholder = document.getElementById('ceo-tagcloud-placeholder'); | |||
if (!placeholder) return; | |||
// Build the HTML structure | |||
var tagCloudHTML = '<div class="mp-card" style="margin-top: 1em;">' + | |||
'<div class="mp-card-title">Explore Popular Topics</div>' + | |||
'<div class="mp-card-content" style="padding: 2em 1em;">' + | |||
'<div style="text-align: center; margin-bottom: 1em; color: #54595d;">Interactive 3D cloud of most popular pages</div>' + | |||
'<div id="tagcloud-container" style="width: 100%; height: 350px; position: relative; perspective: 800px; background: radial-gradient(circle at center, #f8f9fa 0%, #e5e7eb 100%); border-radius: 12px; overflow: hidden; box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.05);">' + | |||
'<div id="tagcloud-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.85em; color: #6b7280;"><em>Hover and move mouse to rotate</em></div>' + | |||
'</div></div>'; | |||
placeholder.innerHTML = tagCloudHTML; | |||
// Tag data | |||
var tags = [ | |||
{text: 'Satya Nadella', href: '/wiki/Satya_Nadella', weight: 10}, | |||
{text: 'Tim Cook', href: '/wiki/Tim_Cook', weight: 9}, | |||
{text: 'Mary Barra', href: '/wiki/Mary_Barra', weight: 8}, | |||
{text: 'Andy Jassy', href: '/wiki/Andy_Jassy', weight: 9}, | |||
{text: 'Sundar Pichai', href: '/wiki/Sundar_Pichai', weight: 10}, | |||
{text: 'CEO Profiles', href: '/wiki/Category:Chief_executive_officers', weight: 7}, | |||
{text: 'Companies', href: '/wiki/Category:Companies', weight: 6}, | |||
{text: 'Business Strategy', href: '/wiki/Category:Business_strategies', weight: 5}, | |||
{text: 'Governance', href: '/wiki/Category:Corporate_governance', weight: 5}, | |||
{text: 'CEOs by Country', href: '/wiki/Category:CEOs_by_country', weight: 6}, | |||
{text: 'American CEOs', href: '/wiki/Category:American_CEOs', weight: 7}, | |||
{text: 'Tech CEOs', href: '/wiki/Category:Technology_CEOs', weight: 8}, | |||
{text: 'Random', href: '/wiki/Special:Random', weight: 4}, | |||
{text: 'Industry Analysis', href: '/wiki/Category:Industry_analysis', weight: 5}, | |||
{text: 'Microsoft', href: '/wiki/Microsoft', weight: 7}, | |||
{text: 'Apple', href: '/wiki/Apple_Inc.', weight: 8}, | |||
{text: 'Amazon', href: '/wiki/Amazon', weight: 7}, | |||
{text: 'Google', href: '/wiki/Google', weight: 8}, | |||
{text: 'General Motors', href: '/wiki/General_Motors', weight: 6}, | |||
{text: 'Fortune 500', href: '/wiki/Category:Fortune_500_CEOs', weight: 6} | |||
]; | |||
// Create tag elements | |||
var container = document.getElementById('tagcloud-sphere'); | var container = document.getElementById('tagcloud-sphere'); | ||
if (!container) return; | if (!container) return; | ||
var | tags.forEach(function(tag) { | ||
var a = document.createElement('a'); | |||
a.href = tag.href; | |||
a.className = 'tag-item'; | |||
a.setAttribute('data-weight', tag.weight); | |||
a.textContent = tag.text; | |||
a.style.position = 'absolute'; | |||
a.style.left = '50%'; | |||
a.style.top = '50%'; | |||
a.style.whiteSpace = 'nowrap'; | |||
a.style.textDecoration = 'none'; | |||
a.style.color = '#1e3a5c'; | |||
a.style.fontWeight = '600'; | |||
a.style.padding = '0.4em 0.8em'; | |||
a.style.background = 'linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)'; | |||
a.style.border = '2px solid #0066cc'; | |||
a.style.borderRadius = '20px'; | |||
a.style.cursor = 'pointer'; | |||
a.style.userSelect = 'none'; | |||
a.style.boxShadow = '0 2px 8px rgba(0, 102, 204, 0.2)'; | |||
a.style.transition = 'all 0.3s ease'; | |||
var fontSize = 0.9 + (tag.weight / 10) * 0.5; | |||
a.style.fontSize = fontSize + 'em'; | |||
a.addEventListener('mouseenter', function() { | |||
this.style.background = 'linear-gradient(135deg, #0066cc 0%, #0052a3 100%)'; | |||
this.style.color = '#ffffff'; | |||
this.style.transform = 'scale(1.2)'; | |||
this.style.boxShadow = '0 4px 16px rgba(0, 102, 204, 0.4)'; | |||
this.style.zIndex = '100'; | |||
}); | |||
a.addEventListener('mouseleave', function() { | |||
this.style.background = 'linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)'; | |||
this.style.color = '#1e3a5c'; | |||
this.style.transform = 'scale(1)'; | |||
this.style.boxShadow = '0 2px 8px rgba(0, 102, 204, 0.2)'; | |||
this.style.zIndex = 'auto'; | |||
}); | |||
container.appendChild(a); | |||
}); | |||
var radius = | // 3D Animation Engine | ||
var elements = container.getElementsByClassName('tag-item'); | |||
var radius = 150; | |||
var dtr = Math.PI / 180; | var dtr = Math.PI / 180; | ||
var mcList = []; | var mcList = []; | ||
var active = false; | var active = false; | ||
var lasta = | var lasta = 0.5; | ||
var lastb = | var lastb = 0.5; | ||
var tspeed = 2; | var tspeed = 2; | ||
var size = | var size = 200; | ||
var mouseX = 0; | var mouseX = 0; | ||
var mouseY = 0; | var mouseY = 0; | ||
var sa, ca, sb, cb, sc, cc; | |||
var | |||
// | // Initialize positions | ||
for (var i = 0; i < elements.length; i++) { | |||
var oTag = {}; | |||
oTag.offsetWidth = elements[i].offsetWidth; | |||
for (i = 0; i < | oTag.offsetHeight = elements[i].offsetHeight; | ||
oTag = {}; | |||
oTag.offsetWidth = | |||
oTag.offsetHeight = | |||
mcList.push(oTag); | mcList.push(oTag); | ||
} | } | ||
sineCosine(0, 0, 0); | sineCosine(0, 0, 0); | ||
positionAll(); | positionAll(); | ||
setInterval(update, 30); | |||
function update() { | function update() { | ||
var a | var a, b; | ||
if (active) { | if (active) { | ||
| Line 60: | Line 136: | ||
if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01 && !active) { | if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01 && !active) { | ||
a = 0.3; | a = 0.3; | ||
b = 0.3; | b = 0.3; | ||
} | } | ||
sineCosine(a, b, 0); | |||
sineCosine(a, b, | |||
for (var i = 0; i < mcList.length; i++) { | for (var i = 0; i < mcList.length; i++) { | ||
| Line 77: | Line 151: | ||
var rz2 = rx1 * (-sb) + rz1 * cb; | var rz2 = rx1 * (-sb) + rz1 * cb; | ||
mcList[i].cx = rx2; | |||
mcList[i].cy = ry2; | |||
mcList[i].cz = rz2; | |||
mcList[i].cx = | |||
mcList[i].cy = | |||
mcList[i].cz = | |||
mcList[i].x = | var per = 350 / (350 + rz2); | ||
mcList[i].y = | mcList[i].x = rx2 * per; | ||
mcList[i].y = ry2 * per; | |||
mcList[i].scale = per; | mcList[i].scale = per; | ||
mcList[i].alpha = per; | mcList[i].alpha = per; | ||
mcList[i].alpha = (mcList[i].alpha - 0.6) * (10 / 6); | mcList[i].alpha = (mcList[i].alpha - 0.6) * (10 / 6); | ||
} | } | ||
| Line 100: | Line 168: | ||
function depthSort() { | function depthSort() { | ||
var aTmp = []; | var aTmp = []; | ||
for (var i = 0; i < elements.length; i++) { | |||
for (i = 0; i < | aTmp.push(elements[i]); | ||
aTmp.push( | elements[i].cz = mcList[i].cz; | ||
} | } | ||
aTmp.sort(function(vItem1, vItem2) { | aTmp.sort(function(vItem1, vItem2) { | ||
if (vItem1.cz > vItem2.cz) | if (vItem1.cz > vItem2.cz) return -1; | ||
else if (vItem1.cz < vItem2.cz) return 1; | |||
else return 0; | |||
}); | }); | ||
for (i = 0; i < aTmp.length; i++) { | for (var i = 0; i < aTmp.length; i++) { | ||
aTmp[i].style.zIndex = i; | aTmp[i].style.zIndex = i; | ||
} | } | ||
| Line 123: | Line 186: | ||
function positionAll() { | function positionAll() { | ||
var phi | var phi, theta, max = mcList.length; | ||
for (var i = 0; i < max; i++) { | for (var i = 0; i < max; i++) { | ||
| Line 137: | Line 196: | ||
mcList[i].cz = radius * Math.cos(phi); | mcList[i].cz = radius * Math.cos(phi); | ||
elements[i].style.left = mcList[i].cx + container.offsetWidth / 2 - mcList[i].offsetWidth / 2 + 'px'; | |||
elements[i].style.top = mcList[i].cy + container.offsetHeight / 2 - mcList[i].offsetHeight / 2 + 'px'; | |||
} | } | ||
} | } | ||
function doPosition() { | function doPosition() { | ||
var l = | var l = container.offsetWidth / 2; | ||
var t = | var t = container.offsetHeight / 2; | ||
for (var i = 0; i < mcList.length; i++) { | for (var i = 0; i < mcList.length; i++) { | ||
var item = | var item = elements[i]; | ||
var mc = mcList[i]; | var mc = mcList[i]; | ||
| Line 153: | Line 212: | ||
item.style.top = mc.y + t - mc.offsetHeight / 2 + 'px'; | item.style.top = mc.y + t - mc.offsetHeight / 2 + 'px'; | ||
item. | var baseSize = parseFloat(item.getAttribute('data-weight')) / 10; | ||
item.style. | item.style.fontSize = (0.9 + baseSize * 0.5) * mc.scale + 'em'; | ||
item.style.opacity = mc.alpha; | item.style.opacity = Math.max(0.3, mc.alpha); | ||
} | } | ||
} | } | ||
| Line 168: | Line 227: | ||
} | } | ||
// Mouse | // Mouse interaction | ||
var | var containerElem = document.getElementById('tagcloud-container'); | ||
containerElem.addEventListener('mouseover', function() { | |||
active = true; | active = true; | ||
}); | }); | ||
containerElem.addEventListener('mouseout', function() { | |||
active = false; | active = false; | ||
}); | }); | ||
containerElem.addEventListener('mousemove', function(ev) { | |||
var rect = containerElem.getBoundingClientRect(); | |||
var rect = | mouseX = ev.clientX - rect.left - containerElem.offsetWidth / 2; | ||
mouseY = ev.clientY - rect.top - containerElem.offsetHeight / 2; | |||
mouseY = | |||
}); | }); | ||
} | } | ||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
document.addEventListener('DOMContentLoaded', | document.addEventListener('DOMContentLoaded', buildAndInitTagCloud); | ||
} else { | } else { | ||
buildAndInitTagCloud(); | |||
} | } | ||
})(); | })(); | ||
Revision as of 12:12, 19 October 2025
/* 3D Tag Cloud - Dynamic Builder */
(function() {
if (typeof window.CEOTagCloudInit !== 'undefined') return;
window.CEOTagCloudInit = true;
function buildAndInitTagCloud() {
var placeholder = document.getElementById('ceo-tagcloud-placeholder');
if (!placeholder) return;
// Build the HTML structure
var tagCloudHTML = '<div class="mp-card" style="margin-top: 1em;">' +
'<div class="mp-card-title">Explore Popular Topics</div>' +
'<div class="mp-card-content" style="padding: 2em 1em;">' +
'<div style="text-align: center; margin-bottom: 1em; color: #54595d;">Interactive 3D cloud of most popular pages</div>' +
'<div id="tagcloud-container" style="width: 100%; height: 350px; position: relative; perspective: 800px; background: radial-gradient(circle at center, #f8f9fa 0%, #e5e7eb 100%); border-radius: 12px; overflow: hidden; box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.05);">' +
'<div id="tagcloud-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.85em; color: #6b7280;"><em>Hover and move mouse to rotate</em></div>' +
'</div></div>';
placeholder.innerHTML = tagCloudHTML;
// Tag data
var tags = [
{text: 'Satya Nadella', href: '/wiki/Satya_Nadella', weight: 10},
{text: 'Tim Cook', href: '/wiki/Tim_Cook', weight: 9},
{text: 'Mary Barra', href: '/wiki/Mary_Barra', weight: 8},
{text: 'Andy Jassy', href: '/wiki/Andy_Jassy', weight: 9},
{text: 'Sundar Pichai', href: '/wiki/Sundar_Pichai', weight: 10},
{text: 'CEO Profiles', href: '/wiki/Category:Chief_executive_officers', weight: 7},
{text: 'Companies', href: '/wiki/Category:Companies', weight: 6},
{text: 'Business Strategy', href: '/wiki/Category:Business_strategies', weight: 5},
{text: 'Governance', href: '/wiki/Category:Corporate_governance', weight: 5},
{text: 'CEOs by Country', href: '/wiki/Category:CEOs_by_country', weight: 6},
{text: 'American CEOs', href: '/wiki/Category:American_CEOs', weight: 7},
{text: 'Tech CEOs', href: '/wiki/Category:Technology_CEOs', weight: 8},
{text: 'Random', href: '/wiki/Special:Random', weight: 4},
{text: 'Industry Analysis', href: '/wiki/Category:Industry_analysis', weight: 5},
{text: 'Microsoft', href: '/wiki/Microsoft', weight: 7},
{text: 'Apple', href: '/wiki/Apple_Inc.', weight: 8},
{text: 'Amazon', href: '/wiki/Amazon', weight: 7},
{text: 'Google', href: '/wiki/Google', weight: 8},
{text: 'General Motors', href: '/wiki/General_Motors', weight: 6},
{text: 'Fortune 500', href: '/wiki/Category:Fortune_500_CEOs', weight: 6}
];
// Create tag elements
var container = document.getElementById('tagcloud-sphere');
if (!container) return;
tags.forEach(function(tag) {
var a = document.createElement('a');
a.href = tag.href;
a.className = 'tag-item';
a.setAttribute('data-weight', tag.weight);
a.textContent = tag.text;
a.style.position = 'absolute';
a.style.left = '50%';
a.style.top = '50%';
a.style.whiteSpace = 'nowrap';
a.style.textDecoration = 'none';
a.style.color = '#1e3a5c';
a.style.fontWeight = '600';
a.style.padding = '0.4em 0.8em';
a.style.background = 'linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)';
a.style.border = '2px solid #0066cc';
a.style.borderRadius = '20px';
a.style.cursor = 'pointer';
a.style.userSelect = 'none';
a.style.boxShadow = '0 2px 8px rgba(0, 102, 204, 0.2)';
a.style.transition = 'all 0.3s ease';
var fontSize = 0.9 + (tag.weight / 10) * 0.5;
a.style.fontSize = fontSize + 'em';
a.addEventListener('mouseenter', function() {
this.style.background = 'linear-gradient(135deg, #0066cc 0%, #0052a3 100%)';
this.style.color = '#ffffff';
this.style.transform = 'scale(1.2)';
this.style.boxShadow = '0 4px 16px rgba(0, 102, 204, 0.4)';
this.style.zIndex = '100';
});
a.addEventListener('mouseleave', function() {
this.style.background = 'linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)';
this.style.color = '#1e3a5c';
this.style.transform = 'scale(1)';
this.style.boxShadow = '0 2px 8px rgba(0, 102, 204, 0.2)';
this.style.zIndex = 'auto';
});
container.appendChild(a);
});
// 3D Animation Engine
var elements = container.getElementsByClassName('tag-item');
var radius = 150;
var dtr = Math.PI / 180;
var mcList = [];
var active = false;
var lasta = 0.5;
var lastb = 0.5;
var tspeed = 2;
var size = 200;
var mouseX = 0;
var mouseY = 0;
var sa, ca, sb, cb, sc, cc;
// Initialize positions
for (var i = 0; i < elements.length; i++) {
var oTag = {};
oTag.offsetWidth = elements[i].offsetWidth;
oTag.offsetHeight = elements[i].offsetHeight;
mcList.push(oTag);
}
sineCosine(0, 0, 0);
positionAll();
setInterval(update, 30);
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;
}
lasta = a;
lastb = b;
if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01 && !active) {
a = 0.3;
b = 0.3;
}
sineCosine(a, b, 0);
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;
mcList[i].cx = rx2;
mcList[i].cy = ry2;
mcList[i].cz = rz2;
var per = 350 / (350 + rz2);
mcList[i].x = rx2 * per;
mcList[i].y = ry2 * per;
mcList[i].scale = per;
mcList[i].alpha = per;
mcList[i].alpha = (mcList[i].alpha - 0.6) * (10 / 6);
}
doPosition();
depthSort();
}
function depthSort() {
var aTmp = [];
for (var i = 0; i < elements.length; i++) {
aTmp.push(elements[i]);
elements[i].cz = mcList[i].cz;
}
aTmp.sort(function(vItem1, vItem2) {
if (vItem1.cz > vItem2.cz) return -1;
else if (vItem1.cz < vItem2.cz) return 1;
else return 0;
});
for (var i = 0; i < aTmp.length; i++) {
aTmp[i].style.zIndex = i;
}
}
function positionAll() {
var phi, theta, max = mcList.length;
for (var i = 0; i < max; i++) {
phi = Math.acos(-1 + (2 * i) / 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);
elements[i].style.left = mcList[i].cx + container.offsetWidth / 2 - mcList[i].offsetWidth / 2 + 'px';
elements[i].style.top = mcList[i].cy + container.offsetHeight / 2 - mcList[i].offsetHeight / 2 + 'px';
}
}
function doPosition() {
var l = container.offsetWidth / 2;
var t = container.offsetHeight / 2;
for (var i = 0; i < mcList.length; i++) {
var item = elements[i];
var mc = mcList[i];
item.style.left = mc.x + l - mc.offsetWidth / 2 + 'px';
item.style.top = mc.y + t - mc.offsetHeight / 2 + 'px';
var baseSize = parseFloat(item.getAttribute('data-weight')) / 10;
item.style.fontSize = (0.9 + baseSize * 0.5) * mc.scale + 'em';
item.style.opacity = Math.max(0.3, mc.alpha);
}
}
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);
}
// Mouse interaction
var containerElem = document.getElementById('tagcloud-container');
containerElem.addEventListener('mouseover', function() {
active = true;
});
containerElem.addEventListener('mouseout', function() {
active = false;
});
containerElem.addEventListener('mousemove', function(ev) {
var rect = containerElem.getBoundingClientRect();
mouseX = ev.clientX - rect.left - containerElem.offsetWidth / 2;
mouseY = ev.clientY - rect.top - containerElem.offsetHeight / 2;
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', buildAndInitTagCloud);
} else {
buildAndInitTagCloud();
}
})();