MediaWiki:Common.js: Difference between revisions
Appearance
Increased tag cloud text size by 300% and changed to Wikipedia-style serif font (Linux Libertine, Georgia) |
FIX: 1) Moved cloud up 30px for proper centering 2) Removed backface-visibility:hidden so text never disappears, just fades to 25% opacity when behind |
||
| (19 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
/** | /* Common.js - Site-wide JavaScript */ | ||
/* Add copyright footer at the very bottom of page - single occurrence only */ | |||
(function() { | $(document).ready(function() { | ||
// | // Remove any existing copyright footers first to prevent duplicates | ||
$('#footer-info-copyright, .ceo-copyright-footer').remove(); | |||
// Create the copyright footer | |||
var copyright = '<div class="ceo-copyright-footer" id="footer-info-copyright" style="text-align: center; padding: 20px; background: #f8f9fa; border-top: 1px solid #ddd; margin-top: 40px; font-size: 0.85em; line-height: 1.6;">Text is available under the <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="nofollow">Creative Commons Attribution-ShareAlike 4.0 License</a>; additional terms may apply. By using this site, you agree to the <a href="/wiki/CEO.wiki:Terms_of_Use">Terms of Use</a>, <a href="/wiki/CEO.wiki:Privacy_Policy">Privacy Policy</a>, and all <a href="/wiki/CEO.wiki:General_disclaimer">disclaimers</a>. CEO.wiki is operated as an independent collaborative encyclopedia project and is not affiliated with Wikipedia or the Wikimedia Foundation. See our <a href="/wiki/CEO.wiki:Takedown_Request_Policy">Takedown Request Policy</a> for content concerns.</div>'; | |||
// Append to the very bottom of the body | |||
$('body').append(copyright); | |||
}); | |||
/* 3D CEO Cloud - FIXED centering and visibility */ | |||
$(document).ready(function() { | |||
var placeholder = document.getElementById('ceocloud-placeholder'); | |||
if (!placeholder) return; | |||
var ceoDataEl = document.getElementById('ceo-data'); | |||
if (!ceoDataEl) return; | |||
var ceoDataJson = ceoDataEl.getAttribute('data-ceos'); | |||
if (!ceoDataJson) return; | |||
var tags; | |||
try { | |||
tags = JSON.parse(ceoDataJson); | |||
} catch(e) { | |||
console.log('CEO Cloud: JSON parse error'); | |||
return; | return; | ||
} | } | ||
if (!tags || tags.length === 0) return; | |||
console.log('CEO Cloud: Initializing with ' + tags.length + ' CEOs'); | |||
// Create cloud container | |||
var cloud = document.createElement('div'); | |||
cloud.style.cssText = 'position:relative;width:100%;height:500px;overflow:hidden;cursor:grab;'; | |||
// Create sphere container - FIXED: moved up by 30px to compensate for visual offset | |||
var sphere = document.createElement('div'); | |||
sphere.style.cssText = 'position:absolute;left:50%;top:calc(50% - 30px);width:1px;height:1px;transform-style:preserve-3d;will-change:transform;'; | |||
// Ellipsoid parameters | |||
var radiusX = 320; | |||
var radiusY = 100; | |||
var radiusZ = 240; | |||
var phi = Math.PI * (3 - Math.sqrt(5)); | |||
var ceoElements = []; | |||
var numTags = tags.length; | |||
// Pre-calculate positions and create elements | |||
for (var i = 0; i < numTags; i++) { | |||
var tag = tags[i]; | |||
var y = 1 - (i / (numTags - 1)) * 2; | |||
var radiusAtY = Math.sqrt(1 - y * y); | |||
var theta = phi * i; | |||
var x = Math.cos(theta) * radiusAtY; | |||
var z = Math.sin(theta) * radiusAtY; | |||
var posX = x * radiusX; | |||
var posY = y * radiusY; | |||
var posZ = z * radiusZ; | |||
var link = document.createElement('a'); | |||
link.href = tag.url; | |||
link.textContent = tag.text; | |||
// FIXED: Removed backface-visibility:hidden so text is always visible | |||
link.style.cssText = 'position:absolute;left:0;top:0;color:#fff;text-decoration:none;font-size:' + tag.size + 'px;font-weight:400;font-family:"Linux Libertine",Georgia,serif;white-space:nowrap;text-shadow:0 2px 10px rgba(0,0,0,0.9);cursor:pointer;transform-style:preserve-3d;user-select:none;will-change:transform,opacity;transform:translate3d(' + posX + 'px,' + posY + 'px,' + posZ + 'px) translate(-50%,-50%);'; | |||
link.dataset.x = posX; | |||
link.dataset.y = posY; | |||
link.dataset.z = posZ; | |||
link.dataset.size = tag.size; | |||
// Hover effects | |||
link.onmouseenter = function() { | |||
this.style.color = '#fbbf24'; | |||
this.style.fontWeight = '700'; | |||
this.style.fontSize = (parseFloat(this.dataset.size) * 1.4) + 'px'; | |||
this.style.textShadow = '0 3px 20px rgba(251,191,36,1),0 0 50px rgba(251,191,36,0.8)'; | |||
this.style.zIndex = '1000'; | |||
}; | |||
link.onmouseleave = function() { | |||
this.style.color = '#fff'; | |||
this.style.fontWeight = '400'; | |||
this.style.fontSize = this.dataset.size + 'px'; | |||
this.style.textShadow = '0 2px 10px rgba(0,0,0,0.9)'; | |||
this.style.zIndex = ''; | |||
}; | |||
ceoElements.push({ el: link, x: posX, y: posY, z: posZ }); | |||
sphere.appendChild(link); | |||
} | } | ||
cloud.appendChild(sphere); | |||
placeholder.innerHTML = ''; | |||
placeholder.appendChild(cloud); | |||
' | // Animation state | ||
var angleX = 10, angleY = 0; | |||
var targetAngleX = 10, targetAngleY = 0; | |||
var zoom = 1.7, targetZoom = 1.7; | |||
// | var autoRotate = true; | ||
var rotationSpeed = 0.15; | |||
var | var frameCount = 0; | ||
// FIXED: Proper depth calculation - text always visible, just faded when behind | |||
function updateDepth() { | |||
var rad = angleY * Math.PI / 180; | |||
var cosRad = Math.cos(rad); | |||
var sinRad = Math.sin(rad); | |||
for (var i = 0; i < ceoElements.length; i++) { | |||
var ceo = ceoElements[i]; | |||
// Calculate rotated Z position | |||
var newZ = ceo.z * cosRad - ceo.x * sinRad; | |||
// Normalize to 0-1 range (front to back) | |||
var depthFactor = (newZ + radiusZ) / (radiusZ * 2); | |||
depthFactor = Math.max(0, Math.min(1, depthFactor)); | |||
// FIXED: Text at back (depthFactor near 0) still visible but faded | |||
// Front text: opacity 1.0, Back text: opacity 0.25 | |||
var opacity = 0.25 + depthFactor * 0.75; | |||
ceo.el.style.opacity = opacity; | |||
ceo.el.style.zIndex = Math.round(depthFactor * 100); | |||
} | } | ||
} | } | ||
// Main animation loop | |||
function animate() { | |||
if (autoRotate) { | |||
function | targetAngleY += rotationSpeed; | ||
} | |||
// | // Smooth interpolation | ||
angleX += (targetAngleX - angleX) * 0.1; | |||
angleY += (targetAngleY - angleY) * 0.1; | |||
zoom += (targetZoom - zoom) * 0.1; | |||
// Update transform | |||
sphere.style.transform = 'scale(' + zoom + ') rotateX(' + angleX + 'deg) rotateY(' + angleY + 'deg)'; | |||
// Update depth every 3 frames for performance | |||
frameCount++; | |||
if (frameCount % 3 === 0) { | |||
updateDepth(); | |||
} | } | ||
requestAnimationFrame(animate); | |||
} | |||
// Initial depth calculation | |||
updateDepth(); | |||
animate(); | |||
// Mouse drag controls | |||
var isDragging = false, prevX = 0, prevY = 0; | |||
cloud.onmousedown = function(e) { | |||
if (e.target.tagName !== 'A') { | |||
isDragging = true; | |||
autoRotate = false; | |||
prevX = e.clientX; | |||
prevY = e.clientY; | |||
cloud.style.cursor = 'grabbing'; | |||
e.preventDefault(); | |||
} | } | ||
}; | |||
document.onmousemove = function(e) { | |||
if (isDragging) { | |||
targetAngleY += (e.clientX - prevX) * 0.5; | |||
targetAngleX = Math.max(-40, Math.min(40, targetAngleX - (e.clientY - prevY) * 0.3)); | |||
prevX = e.clientX; | |||
prevY = e.clientY; | |||
} | } | ||
}; | |||
document.onmouseup = function() { | |||
if (isDragging) { | |||
isDragging = false; | |||
cloud.style.cursor = 'grab'; | |||
setTimeout(function() { autoRotate = true; }, 2000); | |||
} | } | ||
}; | |||
// Mouse wheel zoom | |||
cloud.onwheel = function(e) { | |||
e.preventDefault(); | |||
targetZoom = Math.max(0.8, Math.min(2.5, targetZoom + (e.deltaY > 0 ? -0.1 : 0.1))); | |||
autoRotate = false; | |||
clearTimeout(cloud.zoomTimeout); | |||
cloud.zoomTimeout = setTimeout(function() { autoRotate = true; }, 1500); | |||
}; | |||
// Touch support | |||
cloud.ontouchstart = function(e) { | |||
if (e.touches.length === 1) { | |||
isDragging = true; | |||
autoRotate = false; | |||
prevX = e.touches[0].clientX; | |||
prevY = e.touches[0].clientY; | |||
e.preventDefault(); | |||
} | } | ||
}; | |||
document.ontouchmove = function(e) { | |||
if (isDragging && e.touches.length === 1) { | |||
targetAngleY += (e.touches[0].clientX - prevX) * 0.5; | |||
targetAngleX = Math.max(-40, Math.min(40, targetAngleX - (e.touches[0].clientY - prevY) * 0.3)); | |||
prevX = e.touches[0].clientX; | |||
prevY = e.touches[0].clientY; | |||
} | } | ||
}; | |||
document.ontouchend = function() { | |||
if (isDragging) { | |||
isDragging = false; | |||
setTimeout(function() { autoRotate = true; }, 2000); | |||
} | } | ||
}; | |||
// Control hints | |||
var hints = document.createElement('div'); | |||
hints.style.cssText = 'position:absolute;bottom:10px;left:50%;transform:translateX(-50%);color:rgba(255,255,255,0.6);font-size:12px;text-align:center;pointer-events:none;font-family:sans-serif;'; | |||
hints.innerHTML = '🖱️ Drag to rotate • 🔍 Scroll to zoom'; | |||
cloud.appendChild(hints); | |||
console.log('CEO Cloud: Initialization complete'); | |||
}); | |||
/* ============================================ | |||
RESPONSIVE CEO PROFILE IMAGES | |||
============================================ */ | |||
$(document).ready(function() { | |||
if (!$('body').hasClass('page-Main_Page')) return; | |||
function resizeCEOImages() { | |||
var windowWidth = $(window).width(); | |||
var imageWidth; | |||
if (windowWidth > 1200) { | |||
imageWidth = Math.floor((windowWidth - 100) / 3 * 0.7); | |||
} else if (windowWidth > 768) { | |||
imageWidth = Math.floor((windowWidth - 80) / 2 * 0.7); | |||
} else if (windowWidth > 480) { | |||
imageWidth = Math.floor((windowWidth - 40) * 0.8); | |||
} else { | |||
imageWidth = Math.floor((windowWidth - 40) * 0.9); | |||
} | } | ||
imageWidth = Math.max(150, Math.min(400, imageWidth)); | |||
$('table[style*="width: 33%"] img, table[style*="width: 25%"] img').each(function() { | |||
var $img = $(this); | |||
var src = $img.attr('src'); | |||
if (!src || src.indexOf('File:') === -1) return; | |||
if (src.indexOf('/thumb/') !== -1) { | |||
$img.attr('src', src.replace(/\/\d+px-/, '/' + imageWidth + 'px-')); | |||
var | |||
} | } | ||
$img.css({ 'max-width': '100%', 'height': 'auto', 'width': 'auto', 'display': 'block', 'margin': '0 auto' }); | |||
$img.removeAttr('width').removeAttr('height'); | |||
$img.parent('a').css({ 'display': 'block', 'text-align': 'center' }); | |||
}); | |||
} | } | ||
resizeCEOImages(); | |||
})(); | var resizeTimer; | ||
$(window).on('resize', function() { | |||
clearTimeout(resizeTimer); | |||
resizeTimer = setTimeout(resizeCEOImages, 250); | |||
}); | |||
$(window).on('orientationchange', function() { | |||
setTimeout(resizeCEOImages, 300); | |||
}); | |||
}); | |||
Latest revision as of 12:24, 29 November 2025
/* Common.js - Site-wide JavaScript */
/* Add copyright footer at the very bottom of page - single occurrence only */
$(document).ready(function() {
// Remove any existing copyright footers first to prevent duplicates
$('#footer-info-copyright, .ceo-copyright-footer').remove();
// Create the copyright footer
var copyright = '<div class="ceo-copyright-footer" id="footer-info-copyright" style="text-align: center; padding: 20px; background: #f8f9fa; border-top: 1px solid #ddd; margin-top: 40px; font-size: 0.85em; line-height: 1.6;">Text is available under the <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="nofollow">Creative Commons Attribution-ShareAlike 4.0 License</a>; additional terms may apply. By using this site, you agree to the <a href="/wiki/CEO.wiki:Terms_of_Use">Terms of Use</a>, <a href="/wiki/CEO.wiki:Privacy_Policy">Privacy Policy</a>, and all <a href="/wiki/CEO.wiki:General_disclaimer">disclaimers</a>. CEO.wiki is operated as an independent collaborative encyclopedia project and is not affiliated with Wikipedia or the Wikimedia Foundation. See our <a href="/wiki/CEO.wiki:Takedown_Request_Policy">Takedown Request Policy</a> for content concerns.</div>';
// Append to the very bottom of the body
$('body').append(copyright);
});
/* 3D CEO Cloud - FIXED centering and visibility */
$(document).ready(function() {
var placeholder = document.getElementById('ceocloud-placeholder');
if (!placeholder) return;
var ceoDataEl = document.getElementById('ceo-data');
if (!ceoDataEl) return;
var ceoDataJson = ceoDataEl.getAttribute('data-ceos');
if (!ceoDataJson) return;
var tags;
try {
tags = JSON.parse(ceoDataJson);
} catch(e) {
console.log('CEO Cloud: JSON parse error');
return;
}
if (!tags || tags.length === 0) return;
console.log('CEO Cloud: Initializing with ' + tags.length + ' CEOs');
// Create cloud container
var cloud = document.createElement('div');
cloud.style.cssText = 'position:relative;width:100%;height:500px;overflow:hidden;cursor:grab;';
// Create sphere container - FIXED: moved up by 30px to compensate for visual offset
var sphere = document.createElement('div');
sphere.style.cssText = 'position:absolute;left:50%;top:calc(50% - 30px);width:1px;height:1px;transform-style:preserve-3d;will-change:transform;';
// Ellipsoid parameters
var radiusX = 320;
var radiusY = 100;
var radiusZ = 240;
var phi = Math.PI * (3 - Math.sqrt(5));
var ceoElements = [];
var numTags = tags.length;
// Pre-calculate positions and create elements
for (var i = 0; i < numTags; i++) {
var tag = tags[i];
var y = 1 - (i / (numTags - 1)) * 2;
var radiusAtY = Math.sqrt(1 - y * y);
var theta = phi * i;
var x = Math.cos(theta) * radiusAtY;
var z = Math.sin(theta) * radiusAtY;
var posX = x * radiusX;
var posY = y * radiusY;
var posZ = z * radiusZ;
var link = document.createElement('a');
link.href = tag.url;
link.textContent = tag.text;
// FIXED: Removed backface-visibility:hidden so text is always visible
link.style.cssText = 'position:absolute;left:0;top:0;color:#fff;text-decoration:none;font-size:' + tag.size + 'px;font-weight:400;font-family:"Linux Libertine",Georgia,serif;white-space:nowrap;text-shadow:0 2px 10px rgba(0,0,0,0.9);cursor:pointer;transform-style:preserve-3d;user-select:none;will-change:transform,opacity;transform:translate3d(' + posX + 'px,' + posY + 'px,' + posZ + 'px) translate(-50%,-50%);';
link.dataset.x = posX;
link.dataset.y = posY;
link.dataset.z = posZ;
link.dataset.size = tag.size;
// Hover effects
link.onmouseenter = function() {
this.style.color = '#fbbf24';
this.style.fontWeight = '700';
this.style.fontSize = (parseFloat(this.dataset.size) * 1.4) + 'px';
this.style.textShadow = '0 3px 20px rgba(251,191,36,1),0 0 50px rgba(251,191,36,0.8)';
this.style.zIndex = '1000';
};
link.onmouseleave = function() {
this.style.color = '#fff';
this.style.fontWeight = '400';
this.style.fontSize = this.dataset.size + 'px';
this.style.textShadow = '0 2px 10px rgba(0,0,0,0.9)';
this.style.zIndex = '';
};
ceoElements.push({ el: link, x: posX, y: posY, z: posZ });
sphere.appendChild(link);
}
cloud.appendChild(sphere);
placeholder.innerHTML = '';
placeholder.appendChild(cloud);
// Animation state
var angleX = 10, angleY = 0;
var targetAngleX = 10, targetAngleY = 0;
var zoom = 1.7, targetZoom = 1.7;
var autoRotate = true;
var rotationSpeed = 0.15;
var frameCount = 0;
// FIXED: Proper depth calculation - text always visible, just faded when behind
function updateDepth() {
var rad = angleY * Math.PI / 180;
var cosRad = Math.cos(rad);
var sinRad = Math.sin(rad);
for (var i = 0; i < ceoElements.length; i++) {
var ceo = ceoElements[i];
// Calculate rotated Z position
var newZ = ceo.z * cosRad - ceo.x * sinRad;
// Normalize to 0-1 range (front to back)
var depthFactor = (newZ + radiusZ) / (radiusZ * 2);
depthFactor = Math.max(0, Math.min(1, depthFactor));
// FIXED: Text at back (depthFactor near 0) still visible but faded
// Front text: opacity 1.0, Back text: opacity 0.25
var opacity = 0.25 + depthFactor * 0.75;
ceo.el.style.opacity = opacity;
ceo.el.style.zIndex = Math.round(depthFactor * 100);
}
}
// Main animation loop
function animate() {
if (autoRotate) {
targetAngleY += rotationSpeed;
}
// Smooth interpolation
angleX += (targetAngleX - angleX) * 0.1;
angleY += (targetAngleY - angleY) * 0.1;
zoom += (targetZoom - zoom) * 0.1;
// Update transform
sphere.style.transform = 'scale(' + zoom + ') rotateX(' + angleX + 'deg) rotateY(' + angleY + 'deg)';
// Update depth every 3 frames for performance
frameCount++;
if (frameCount % 3 === 0) {
updateDepth();
}
requestAnimationFrame(animate);
}
// Initial depth calculation
updateDepth();
animate();
// Mouse drag controls
var isDragging = false, prevX = 0, prevY = 0;
cloud.onmousedown = function(e) {
if (e.target.tagName !== 'A') {
isDragging = true;
autoRotate = false;
prevX = e.clientX;
prevY = e.clientY;
cloud.style.cursor = 'grabbing';
e.preventDefault();
}
};
document.onmousemove = function(e) {
if (isDragging) {
targetAngleY += (e.clientX - prevX) * 0.5;
targetAngleX = Math.max(-40, Math.min(40, targetAngleX - (e.clientY - prevY) * 0.3));
prevX = e.clientX;
prevY = e.clientY;
}
};
document.onmouseup = function() {
if (isDragging) {
isDragging = false;
cloud.style.cursor = 'grab';
setTimeout(function() { autoRotate = true; }, 2000);
}
};
// Mouse wheel zoom
cloud.onwheel = function(e) {
e.preventDefault();
targetZoom = Math.max(0.8, Math.min(2.5, targetZoom + (e.deltaY > 0 ? -0.1 : 0.1)));
autoRotate = false;
clearTimeout(cloud.zoomTimeout);
cloud.zoomTimeout = setTimeout(function() { autoRotate = true; }, 1500);
};
// Touch support
cloud.ontouchstart = function(e) {
if (e.touches.length === 1) {
isDragging = true;
autoRotate = false;
prevX = e.touches[0].clientX;
prevY = e.touches[0].clientY;
e.preventDefault();
}
};
document.ontouchmove = function(e) {
if (isDragging && e.touches.length === 1) {
targetAngleY += (e.touches[0].clientX - prevX) * 0.5;
targetAngleX = Math.max(-40, Math.min(40, targetAngleX - (e.touches[0].clientY - prevY) * 0.3));
prevX = e.touches[0].clientX;
prevY = e.touches[0].clientY;
}
};
document.ontouchend = function() {
if (isDragging) {
isDragging = false;
setTimeout(function() { autoRotate = true; }, 2000);
}
};
// Control hints
var hints = document.createElement('div');
hints.style.cssText = 'position:absolute;bottom:10px;left:50%;transform:translateX(-50%);color:rgba(255,255,255,0.6);font-size:12px;text-align:center;pointer-events:none;font-family:sans-serif;';
hints.innerHTML = '🖱️ Drag to rotate • 🔍 Scroll to zoom';
cloud.appendChild(hints);
console.log('CEO Cloud: Initialization complete');
});
/* ============================================
RESPONSIVE CEO PROFILE IMAGES
============================================ */
$(document).ready(function() {
if (!$('body').hasClass('page-Main_Page')) return;
function resizeCEOImages() {
var windowWidth = $(window).width();
var imageWidth;
if (windowWidth > 1200) {
imageWidth = Math.floor((windowWidth - 100) / 3 * 0.7);
} else if (windowWidth > 768) {
imageWidth = Math.floor((windowWidth - 80) / 2 * 0.7);
} else if (windowWidth > 480) {
imageWidth = Math.floor((windowWidth - 40) * 0.8);
} else {
imageWidth = Math.floor((windowWidth - 40) * 0.9);
}
imageWidth = Math.max(150, Math.min(400, imageWidth));
$('table[style*="width: 33%"] img, table[style*="width: 25%"] img').each(function() {
var $img = $(this);
var src = $img.attr('src');
if (!src || src.indexOf('File:') === -1) return;
if (src.indexOf('/thumb/') !== -1) {
$img.attr('src', src.replace(/\/\d+px-/, '/' + imageWidth + 'px-'));
}
$img.css({ 'max-width': '100%', 'height': 'auto', 'width': 'auto', 'display': 'block', 'margin': '0 auto' });
$img.removeAttr('width').removeAttr('height');
$img.parent('a').css({ 'display': 'block', 'text-align': 'center' });
});
}
resizeCEOImages();
var resizeTimer;
$(window).on('resize', function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(resizeCEOImages, 250);
});
$(window).on('orientationchange', function() {
setTimeout(resizeCEOImages, 300);
});
});