MediaWiki:Common.js: Difference between revisions
Appearance
SuperAdmin1 (talk | contribs) Add JavaScript-based responsive image resizing for CEO profiles - auto-adjusts on window resize |
Zoomed tag cloud 70% more (scale 1.7) and adjusted zoom range (0.8-2.5) |
||
| Line 50: | Line 50: | ||
cloud.style.cursor = 'grab'; | cloud.style.cursor = 'grab'; | ||
// Create inner sphere container | // Create inner sphere container - FIXED: centered properly (was 30% too low) | ||
var sphere = document.createElement('div'); | var sphere = document.createElement('div'); | ||
sphere.style.position = 'absolute'; | sphere.style.position = 'absolute'; | ||
sphere.style.left = '50%'; | sphere.style.left = '50%'; | ||
sphere.style.top = '50%'; | sphere.style.top = '50%'; // True vertical center | ||
sphere.style.width = '1px'; | sphere.style.width = '1px'; | ||
sphere.style.height = '1px'; | sphere.style.height = '1px'; | ||
| Line 149: | Line 149: | ||
placeholder.appendChild(cloud); | placeholder.appendChild(cloud); | ||
// Animation variables | // Animation variables - FIXED: 70% more zoomed (1.7 instead of 1.0) | ||
var angleX = 10; // Start with slight tilt | var angleX = 10; // Start with slight tilt | ||
var angleY = 0; | var angleY = 0; | ||
| Line 156: | Line 156: | ||
var targetAngleY = 0; | var targetAngleY = 0; | ||
var rotationSpeed = 0.15; // Slower, smoother rotation | var rotationSpeed = 0.15; // Slower, smoother rotation | ||
var zoom = 1; | var zoom = 1.7; // CHANGED: Start zoomed in 70% more (was 1) | ||
var targetZoom = 1; | var targetZoom = 1.7; // CHANGED: Target also 1.7 (was 1) | ||
// Update depth-based opacity and size | // Update depth-based opacity and size | ||
| Line 247: | Line 247: | ||
}); | }); | ||
// Mouse wheel zoom | // Mouse wheel zoom - UPDATED: Adjusted zoom limits for new baseline | ||
cloud.addEventListener('wheel', function(e) { | cloud.addEventListener('wheel', function(e) { | ||
e.preventDefault(); | e.preventDefault(); | ||
var delta = e.deltaY > 0 ? -0.1 : 0.1; | var delta = e.deltaY > 0 ? -0.1 : 0.1; | ||
targetZoom = Math.max(0. | targetZoom = Math.max(0.8, Math.min(2.5, targetZoom + delta)); // CHANGED: New range 0.8-2.5 (was 0.5-1.5) | ||
autoRotate = false; | autoRotate = false; | ||
| Line 299: | Line 299: | ||
}); | }); | ||
// Keyboard controls | // Keyboard controls - UPDATED: Adjusted zoom limits | ||
document.addEventListener('keydown', function(e) { | document.addEventListener('keydown', function(e) { | ||
if (placeholder.contains(document.activeElement) || document.activeElement === document.body) { | if (placeholder.contains(document.activeElement) || document.activeElement === document.body) { | ||
| Line 325: | Line 325: | ||
case '+': | case '+': | ||
case '=': | case '=': | ||
targetZoom = Math.min( | targetZoom = Math.min(2.5, targetZoom + 0.1); // CHANGED: max 2.5 (was 1.5) | ||
autoRotate = false; | autoRotate = false; | ||
e.preventDefault(); | e.preventDefault(); | ||
| Line 331: | Line 331: | ||
case '-': | case '-': | ||
case '_': | case '_': | ||
targetZoom = Math.max(0. | targetZoom = Math.max(0.8, targetZoom - 0.1); // CHANGED: min 0.8 (was 0.5) | ||
autoRotate = false; | autoRotate = false; | ||
e.preventDefault(); | e.preventDefault(); | ||
| Line 347: | Line 347: | ||
if (e.target.tagName.toLowerCase() === 'a') { | if (e.target.tagName.toLowerCase() === 'a') { | ||
e.preventDefault(); | e.preventDefault(); | ||
targetZoom = 1.3 | targetZoom = 2.2; // CHANGED: Focus zoom 2.2 (was 1.3) | ||
autoRotate = false; | autoRotate = false; | ||
| Line 370: | Line 370: | ||
cloud.appendChild(hints); | cloud.appendChild(hints); | ||
console.log('CEO Cloud: Successfully initialized with horizontal ellipsoid'); | console.log('CEO Cloud: Successfully initialized with horizontal ellipsoid (zoom: 1.7x)'); | ||
}); | }); | ||
Revision as of 12:05, 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 - Horizontal Ellipsoid - Wikipedia Style */
$(document).ready(function() {
var placeholder = document.getElementById('ceocloud-placeholder');
if (!placeholder) {
console.log('CEO Cloud: placeholder not found');
return;
}
// Get CEO data from the parser function
var ceoDataEl = document.getElementById('ceo-data');
if (!ceoDataEl) {
console.log('CEO Cloud: ceo-data element not found');
return;
}
var ceoDataJson = ceoDataEl.getAttribute('data-ceos');
if (!ceoDataJson) {
console.log('CEO Cloud: data-ceos attribute empty');
return;
}
var tags = JSON.parse(ceoDataJson);
if (!tags || tags.length === 0) {
console.log('CEO Cloud: no tags found');
return;
}
console.log('CEO Cloud: Initializing with ' + tags.length + ' CEOs');
// Create cloud container with proper centering
var cloud = document.createElement('div');
cloud.style.position = 'relative';
cloud.style.width = '100%';
cloud.style.height = '500px';
cloud.style.overflow = 'hidden';
cloud.style.cursor = 'grab';
// Create inner sphere container - FIXED: centered properly (was 30% too low)
var sphere = document.createElement('div');
sphere.style.position = 'absolute';
sphere.style.left = '50%';
sphere.style.top = '50%'; // True vertical center
sphere.style.width = '1px';
sphere.style.height = '1px';
sphere.style.transformStyle = 'preserve-3d';
sphere.style.transition = 'transform 0.3s ease-out';
// Horizontal ellipsoid parameters - much wider than tall
var radiusX = 380; // Width
var radiusY = 120; // Height (much smaller for horizontal spread)
var radiusZ = 280; // Depth
var phi = Math.PI * (3 - Math.sqrt(5)); // Golden angle in radians
var ceoElements = [];
tags.forEach(function(tag, i) {
// Fibonacci sphere distribution
var y = 1 - (i / (tags.length - 1)) * 2; // y goes from 1 to -1
var radiusAtY = Math.sqrt(1 - y * y); // radius at y
var theta = phi * i; // golden angle increment
var x = Math.cos(theta) * radiusAtY;
var z = Math.sin(theta) * radiusAtY;
// Scale to ellipsoid - WIDE horizontally
var posX = x * radiusX;
var posY = y * radiusY;
var posZ = z * radiusZ;
// Create link element
var link = document.createElement('a');
link.href = tag.url;
link.textContent = tag.text;
link.style.position = 'absolute';
link.style.left = '0';
link.style.top = '0';
link.style.color = '#ffffff';
link.style.textDecoration = 'none';
link.style.fontSize = tag.size + 'px';
link.style.fontWeight = '400';
link.style.fontFamily = '"Linux Libertine", Georgia, "Times New Roman", Times, serif';
link.style.whiteSpace = 'nowrap';
link.style.transition = 'all 0.3s ease, transform 0.2s ease';
link.style.textShadow = '0 2px 10px rgba(0,0,0,0.9), 0 0 30px rgba(0,0,0,0.6)';
link.style.cursor = 'pointer';
link.style.transformStyle = 'preserve-3d';
link.style.transform = 'translate3d(' + posX + 'px, ' + posY + 'px, ' + posZ + 'px) translate(-50%, -50%)';
link.style.backfaceVisibility = 'hidden';
link.style.userSelect = 'none';
// Store original position and data
link.dataset.x = posX;
link.dataset.y = posY;
link.dataset.z = posZ;
link.dataset.originalSize = tag.size;
// Hover effects with depth perception
link.addEventListener('mouseenter', function() {
this.style.color = '#fbbf24';
this.style.fontWeight = '700';
var scale = 1.4;
this.style.fontSize = (parseFloat(this.dataset.originalSize) * scale) + 'px';
this.style.textShadow = '0 3px 20px rgba(251, 191, 36, 1), 0 0 50px rgba(251, 191, 36, 0.8), 0 0 80px rgba(251, 191, 36, 0.4)';
this.style.zIndex = '1000';
this.style.filter = 'brightness(1.3)';
});
link.addEventListener('mouseleave', function() {
this.style.color = '#ffffff';
this.style.fontWeight = '400';
this.style.fontSize = this.dataset.originalSize + 'px';
this.style.textShadow = '0 2px 10px rgba(0,0,0,0.9), 0 0 30px rgba(0,0,0,0.6)';
this.style.zIndex = 'auto';
this.style.filter = 'brightness(1)';
});
// Click animation
link.addEventListener('click', function(e) {
this.style.transform = 'translate3d(' + posX + 'px, ' + posY + 'px, ' + (posZ + 100) + 'px) translate(-50%, -50%) scale(1.5)';
this.style.transition = 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)';
});
ceoElements.push({
element: link,
x: posX,
y: posY,
z: posZ
});
sphere.appendChild(link);
});
cloud.appendChild(sphere);
placeholder.innerHTML = ''; // Clear placeholder
placeholder.appendChild(cloud);
// Animation variables - FIXED: 70% more zoomed (1.7 instead of 1.0)
var angleX = 10; // Start with slight tilt
var angleY = 0;
var autoRotate = true;
var targetAngleX = 10;
var targetAngleY = 0;
var rotationSpeed = 0.15; // Slower, smoother rotation
var zoom = 1.7; // CHANGED: Start zoomed in 70% more (was 1)
var targetZoom = 1.7; // CHANGED: Target also 1.7 (was 1)
// Update depth-based opacity and size
function updateDepth() {
var transform = sphere.style.transform;
var matrix = new WebKitCSSMatrix(window.getComputedStyle(sphere).transform);
ceoElements.forEach(function(ceo) {
// Calculate Z position after rotation
var x = parseFloat(ceo.x);
var y = parseFloat(ceo.y);
var z = parseFloat(ceo.z);
// Simple rotation math for depth
var rad = angleY * Math.PI / 180;
var newZ = z * Math.cos(rad) - x * Math.sin(rad);
// Depth-based effects
var depthFactor = (newZ + radiusZ) / (radiusZ * 2); // 0 to 1
var opacity = 0.3 + (depthFactor * 0.7); // 0.3 to 1.0
var scale = 0.7 + (depthFactor * 0.3); // 0.7 to 1.0
ceo.element.style.opacity = opacity;
ceo.element.style.filter = 'brightness(' + (0.6 + depthFactor * 0.4) + ')';
// Update z-index for proper layering
ceo.element.style.zIndex = Math.round(depthFactor * 100);
});
}
function animate() {
if (autoRotate) {
targetAngleY += rotationSpeed;
}
// Smooth interpolation
angleX += (targetAngleX - angleX) * 0.1;
angleY += (targetAngleY - angleY) * 0.1;
zoom += (targetZoom - zoom) * 0.1;
sphere.style.transform = 'scale(' + zoom + ') rotateX(' + angleX + 'deg) rotateY(' + angleY + 'deg)';
updateDepth();
requestAnimationFrame(animate);
}
animate();
// Interactive controls
var isDragging = false;
var previousMouseX = 0;
var previousMouseY = 0;
cloud.addEventListener('mousedown', function(e) {
if (e.target.tagName.toLowerCase() !== 'a') {
isDragging = true;
autoRotate = false;
previousMouseX = e.clientX;
previousMouseY = e.clientY;
cloud.style.cursor = 'grabbing';
e.preventDefault();
}
});
document.addEventListener('mousemove', function(e) {
if (isDragging) {
var deltaX = e.clientX - previousMouseX;
var deltaY = e.clientY - previousMouseY;
targetAngleY += deltaX * 0.5;
targetAngleX -= deltaY * 0.3;
// Limit vertical rotation
targetAngleX = Math.max(-40, Math.min(40, targetAngleX));
previousMouseX = e.clientX;
previousMouseY = e.clientY;
}
});
document.addEventListener('mouseup', function() {
if (isDragging) {
isDragging = false;
cloud.style.cursor = 'grab';
setTimeout(function() {
autoRotate = true;
}, 2000); // Resume auto-rotation after 2 seconds
}
});
// Mouse wheel zoom - UPDATED: Adjusted zoom limits for new baseline
cloud.addEventListener('wheel', function(e) {
e.preventDefault();
var delta = e.deltaY > 0 ? -0.1 : 0.1;
targetZoom = Math.max(0.8, Math.min(2.5, targetZoom + delta)); // CHANGED: New range 0.8-2.5 (was 0.5-1.5)
autoRotate = false;
clearTimeout(cloud.zoomTimeout);
cloud.zoomTimeout = setTimeout(function() {
autoRotate = true;
}, 1500);
});
// Touch support for mobile
var touchStartX = 0;
var touchStartY = 0;
cloud.addEventListener('touchstart', function(e) {
if (e.touches.length === 1) {
isDragging = true;
autoRotate = false;
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
previousMouseX = touchStartX;
previousMouseY = touchStartY;
e.preventDefault();
}
});
document.addEventListener('touchmove', function(e) {
if (isDragging && e.touches.length === 1) {
var deltaX = e.touches[0].clientX - previousMouseX;
var deltaY = e.touches[0].clientY - previousMouseY;
targetAngleY += deltaX * 0.5;
targetAngleX -= deltaY * 0.3;
targetAngleX = Math.max(-40, Math.min(40, targetAngleX));
previousMouseX = e.touches[0].clientX;
previousMouseY = e.touches[0].clientY;
}
});
document.addEventListener('touchend', function() {
if (isDragging) {
isDragging = false;
setTimeout(function() {
autoRotate = true;
}, 2000);
}
});
// Keyboard controls - UPDATED: Adjusted zoom limits
document.addEventListener('keydown', function(e) {
if (placeholder.contains(document.activeElement) || document.activeElement === document.body) {
switch(e.key) {
case 'ArrowLeft':
targetAngleY -= 10;
autoRotate = false;
e.preventDefault();
break;
case 'ArrowRight':
targetAngleY += 10;
autoRotate = false;
e.preventDefault();
break;
case 'ArrowUp':
targetAngleX = Math.max(-40, targetAngleX - 10);
autoRotate = false;
e.preventDefault();
break;
case 'ArrowDown':
targetAngleX = Math.min(40, targetAngleX + 10);
autoRotate = false;
e.preventDefault();
break;
case '+':
case '=':
targetZoom = Math.min(2.5, targetZoom + 0.1); // CHANGED: max 2.5 (was 1.5)
autoRotate = false;
e.preventDefault();
break;
case '-':
case '_':
targetZoom = Math.max(0.8, targetZoom - 0.1); // CHANGED: min 0.8 (was 0.5)
autoRotate = false;
e.preventDefault();
break;
case ' ':
autoRotate = !autoRotate;
e.preventDefault();
break;
}
}
});
// Double-click to focus on CEO
sphere.addEventListener('dblclick', function(e) {
if (e.target.tagName.toLowerCase() === 'a') {
e.preventDefault();
targetZoom = 2.2; // CHANGED: Focus zoom 2.2 (was 1.3)
autoRotate = false;
setTimeout(function() {
window.location.href = e.target.href;
}, 300);
}
});
// Add control hints
var hints = document.createElement('div');
hints.style.position = 'absolute';
hints.style.bottom = '10px';
hints.style.left = '50%';
hints.style.transform = 'translateX(-50%)';
hints.style.color = 'rgba(255,255,255,0.6)';
hints.style.fontSize = '12px';
hints.style.textAlign = 'center';
hints.style.pointerEvents = 'none';
hints.style.fontFamily = 'sans-serif';
hints.innerHTML = '🖱️ Drag to rotate • 🔍 Scroll to zoom • ⌨️ Arrow keys to navigate • Space to pause';
cloud.appendChild(hints);
console.log('CEO Cloud: Successfully initialized with horizontal ellipsoid (zoom: 1.7x)');
});
/* ============================================
RESPONSIVE CEO PROFILE IMAGES
Auto-resize images based on window size
============================================ */
$(document).ready(function() {
// Only run on Main Page
if (!$('body').hasClass('page-Main_Page')) return;
function resizeCEOImages() {
// Get window width
var windowWidth = $(window).width();
// Calculate optimal image width based on screen size
var imageWidth;
if (windowWidth > 1200) {
// Desktop: 3 columns, each ~33%
imageWidth = Math.floor((windowWidth - 100) / 3 * 0.7); // 70% of column width
} else if (windowWidth > 768) {
// Tablet: 2 columns
imageWidth = Math.floor((windowWidth - 80) / 2 * 0.7);
} else if (windowWidth > 480) {
// Mobile landscape: 1 column
imageWidth = Math.floor((windowWidth - 40) * 0.8);
} else {
// Mobile portrait: 1 column, smaller
imageWidth = Math.floor((windowWidth - 40) * 0.9);
}
// Clamp between 150px and 400px
imageWidth = Math.max(150, Math.min(400, imageWidth));
// Find all CEO profile images (images inside featured CEO cards)
$('table[style*="width: 33%"] img, table[style*="width: 25%"] img').each(function() {
var $img = $(this);
// Skip if it's not a CEO profile image
var src = $img.attr('src');
if (!src || src.indexOf('File:') === -1) return;
// Get original src URL without size parameters
var originalSrc = src;
// Build new URL with desired width
// MediaWiki thumb format: /thumb/.../{width}px-filename.jpg
if (src.indexOf('/thumb/') !== -1) {
// Replace the width in the URL
var newSrc = src.replace(/\/\d+px-/, '/' + imageWidth + 'px-');
$img.attr('src', newSrc);
}
// Update img attributes for proper display
$img.css({
'max-width': '100%',
'height': 'auto',
'width': 'auto',
'display': 'block',
'margin': '0 auto'
});
// Remove fixed width attribute if present
$img.removeAttr('width');
$img.removeAttr('height');
// Update parent link styling
$img.parent('a').css({
'display': 'block',
'text-align': 'center'
});
});
console.log('CEO images resized to: ' + imageWidth + 'px (window: ' + windowWidth + 'px)');
}
// Resize on page load
resizeCEOImages();
// Resize on window resize (with debouncing)
var resizeTimer;
$(window).on('resize', function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
resizeCEOImages();
}, 250); // Wait 250ms after resize stops
});
// Also trigger on orientation change (mobile)
$(window).on('orientationchange', function() {
setTimeout(resizeCEOImages, 300);
});
console.log('CEO Profile Images: Responsive resizing enabled');
});