MediaWiki:Common.js: Difference between revisions
Appearance
Updated to true 3D interactive rotating tag cloud - mouse-controlled sphere rotation, depth-based scaling, interactive movement |
Fixed 3D tag cloud - now auto-rotates continuously, uses Canvas for visibility, clickable tags, proper depth sorting |
||
| Line 44: | Line 44: | ||
/** | /** | ||
* 3D | * Simple 3D Rotating Tag Cloud for Main Page | ||
* | * Auto-rotates continuously, very visible | ||
*/ | */ | ||
(function() { | (function() { | ||
| Line 53: | Line 53: | ||
} | } | ||
$(document).ready(function() { | $(document).ready(function() { | ||
var placeholder = document.getElementById('ceo-tagcloud-placeholder'); | var placeholder = document.getElementById('ceo-tagcloud-placeholder'); | ||
if (!placeholder) return; | if (!placeholder) return; | ||
// | // Topics | ||
var topics = [ | var topics = [ | ||
{ text: 'Satya Nadella', url: '/wiki/Satya_Nadella' | { text: 'Satya Nadella', url: '/wiki/Satya_Nadella' }, | ||
{ text: 'Tim Cook', url: '/wiki/Tim_Cook' | { text: 'Tim Cook', url: '/wiki/Tim_Cook' }, | ||
{ text: 'Elon Musk', url: '/wiki/Elon_Musk' | { text: 'Elon Musk', url: '/wiki/Elon_Musk' }, | ||
{ text: 'Mark Zuckerberg', url: '/wiki/Mark_Zuckerberg' | { text: 'Mark Zuckerberg', url: '/wiki/Mark_Zuckerberg' }, | ||
{ text: 'Sundar Pichai', url: '/wiki/Sundar_Pichai' | { text: 'Sundar Pichai', url: '/wiki/Sundar_Pichai' }, | ||
{ text: 'Andy Jassy', url: '/wiki/Andy_Jassy' | { text: 'Andy Jassy', url: '/wiki/Andy_Jassy' }, | ||
{ text: 'Jensen Huang', url: '/wiki/Jensen_Huang' | { text: 'Jensen Huang', url: '/wiki/Jensen_Huang' }, | ||
{ text: 'Lisa Su', url: '/wiki/Lisa_Su' | { text: 'Lisa Su', url: '/wiki/Lisa_Su' }, | ||
{ text: 'Mary Barra', url: '/wiki/Mary_Barra' | { text: 'Mary Barra', url: '/wiki/Mary_Barra' }, | ||
{ text: 'Jamie Dimon', url: '/wiki/Jamie_Dimon' | { text: 'Jamie Dimon', url: '/wiki/Jamie_Dimon' }, | ||
{ text: 'Microsoft', url: '/wiki/Microsoft' | { text: 'Microsoft', url: '/wiki/Microsoft' }, | ||
{ text: 'Apple', url: '/wiki/Apple_Inc.' | { text: 'Apple', url: '/wiki/Apple_Inc.' }, | ||
{ text: 'Amazon', url: '/wiki/Amazon' | { text: 'Amazon', url: '/wiki/Amazon' }, | ||
{ text: 'Google', url: '/wiki/Google' | { text: 'Google', url: '/wiki/Google' }, | ||
{ text: 'Tesla', url: '/wiki/Tesla' | { text: 'Tesla', url: '/wiki/Tesla' }, | ||
{ text: 'Leadership', url: '/wiki/Category:Chief_executive_officers' | { text: 'Leadership', url: '/wiki/Category:Chief_executive_officers' }, | ||
{ text: 'Innovation', url: '/wiki/Category:Business_strategies' | { text: 'Innovation', url: '/wiki/Category:Business_strategies' }, | ||
{ text: 'Technology', url: '/wiki/Category:Companies' | { text: 'Technology', url: '/wiki/Category:Companies' }, | ||
{ text: 'Strategy', url: '/wiki/Category:Business_strategies' | { text: 'Strategy', url: '/wiki/Category:Business_strategies' }, | ||
{ text: 'Cloud Computing', url: '/wiki/Category:Industry_analysis' | { text: 'Cloud Computing', url: '/wiki/Category:Industry_analysis' } | ||
]; | ]; | ||
// Create container | // Create container | ||
var container = | var container = $('<div>').css({ | ||
'background': 'linear-gradient(135deg, #0a1929 0%, #1a2942 50%, #0d2744 100%)', | |||
'padding': '40px 20px', | |||
'border-radius': '12px', | |||
'box-shadow': '0 15px 40px rgba(0,0,0,0.4)', | |||
'min-height': '400px', | |||
'position': 'relative', | |||
'overflow': 'hidden' | |||
}); | |||
// Title | // Title | ||
var title = | var title = $('<div>').text('TRENDING TOPICS').css({ | ||
'color': 'white', | |||
'font-size': '1.4em', | |||
container. | 'font-weight': '700', | ||
'text-align': 'center', | |||
'margin-bottom': '30px', | |||
'text-shadow': '0 4px 10px rgba(0,0,0,0.5)' | |||
}); | |||
container.append(title); | |||
// 3D | // Canvas for 3D cloud | ||
var | var canvas = $('<canvas>').attr({ | ||
'id': 'tagcloud3d-canvas', | |||
'width': '800', | |||
'height': '400' | |||
}).css({ | |||
'display': 'block', | |||
'margin': '0 auto', | |||
'max-width': '100%' | |||
}); | |||
container.append(canvas); | |||
placeholder.appendChild(container[0]); | |||
// | // 3D Tag Cloud Implementation | ||
var | var ctx = canvas[0].getContext('2d'); | ||
var tags = []; | var tags = []; | ||
var radius = 150; | |||
var fallLength = 500; | |||
var angleX = 0; | var angleX = 0; | ||
var angleY = 0; | var angleY = 0; | ||
var | var speedX = 0.01; // Auto-rotation speed | ||
var | var speedY = 0.015; | ||
topics.forEach(function(topic, | // Initialize tags in 3D space | ||
topics.forEach(function(topic, i) { | |||
var phi = Math.acos(-1 + (2 * i) / topics.length); | |||
var phi = Math.acos(-1 + (2 * | |||
var theta = Math.sqrt(topics.length * Math.PI) * phi; | var theta = Math.sqrt(topics.length * Math.PI) * phi; | ||
tags.push({ | |||
text: topic.text, | |||
url: topic.url, | |||
x: radius * Math.sin(phi) * Math.cos(theta), | |||
y: radius * Math.cos(phi), | |||
z: radius * Math.sin(phi) * Math.sin(theta), | |||
originalX: radius * Math.sin(phi) * Math.cos(theta), | |||
originalY: radius * Math.cos(phi), | |||
originalZ: radius * Math.sin(phi) * Math.sin(theta) | |||
}); | |||
}); | |||
// Rotation functions | |||
function rotateX(x, y, z, angle) { | |||
var cos = Math.cos(angle); | |||
var sin = Math.sin(angle); | |||
return { | |||
x: x, | |||
y: y * cos - z * sin, | |||
z: y * sin + z * cos | |||
}; | }; | ||
} | |||
function rotateY(x, y, z, angle) { | |||
var cos = Math.cos(angle); | |||
var sin = Math.sin(angle); | |||
return { | |||
x: x * cos + z * sin, | |||
y: y, | |||
z: -x * sin + z * cos | |||
}; | }; | ||
} | |||
// Animation loop | |||
function animate() { | |||
// Clear canvas | |||
ctx.clearRect(0, 0, canvas[0].width, canvas[0].height); | |||
// Auto-rotate | |||
angleX += speedX; | |||
angleY += speedY; | |||
// Update and draw tags | |||
tags.forEach(function(tag) { | |||
// Apply rotations | |||
var rotated = rotateX(tag.originalX, tag.originalY, tag.originalZ, angleX); | |||
rotated = rotateY(rotated.x, rotated.y, rotated.z, angleY); | |||
tag.x = rotated.x; | |||
tag.y = rotated.y; | |||
tag.z = rotated.z; | |||
}); | |||
// Sort by z-depth (back to front) | |||
tags.sort(function(a, b) { | |||
return a.z - b.z; | |||
}); | |||
// | // Draw tags | ||
tags.forEach(function(tag) { | tags.forEach(function(tag) { | ||
var | var scale = fallLength / (fallLength + tag.z); | ||
var | var x = tag.x * scale + canvas[0].width / 2; | ||
var y = tag.y * scale + canvas[0].height / 2; | |||
var alpha = (tag.z + radius) / (2 * radius); | |||
alpha = Math.max(0.3, Math.min(1, alpha)); | |||
var y = | |||
var | |||
// | // Font size based on depth | ||
var | var fontSize = Math.floor(14 + 10 * scale); | ||
ctx.save(); | |||
ctx.font = fontSize + 'px sans-serif, "Helvetica Neue", Helvetica, Arial'; | |||
ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')'; | |||
ctx.textAlign = 'center'; | |||
tag. | ctx.textBaseline = 'middle'; | ||
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'; | |||
ctx.shadowBlur = 5; | |||
ctx.fillText(tag.text, x, y); | |||
ctx.restore(); | |||
}); | }); | ||
| Line 194: | Line 214: | ||
} | } | ||
// Start animation | |||
animate(); | animate(); | ||
// | // Make tags clickable | ||
var | canvas.on('click', function(e) { | ||
var rect = canvas[0].getBoundingClientRect(); | |||
var x = e.clientX - rect.left; | |||
var y = e.clientY - rect.top; | |||
// Check if click is near any tag | |||
for (var i = tags.length - 1; i >= 0; i--) { | |||
var tag = tags[i]; | |||
var scale = fallLength / (fallLength + tag.z); | |||
var tagX = tag.x * scale + canvas[0].width / 2; | |||
var tagY = tag.y * scale + canvas[0].height / 2; | |||
ctx.font = Math.floor(14 + 10 * scale) + 'px sans-serif'; | |||
var metrics = ctx.measureText(tag.text); | |||
var width = metrics.width; | |||
var height = Math.floor(14 + 10 * scale); | |||
if (x >= tagX - width/2 && x <= tagX + width/2 && | |||
y >= tagY - height/2 && y <= tagY + height/2) { | |||
window.location.href = tag.url; | |||
break; | |||
} | |||
} | |||
}); | |||
// Change cursor on hover | |||
canvas.on('mousemove', function(e) { | |||
var rect = canvas[0].getBoundingClientRect(); | |||
var x = e.clientX - rect.left; | |||
var y = e.clientY - rect.top; | |||
var overTag = false; | |||
for (var i = tags.length - 1; i >= 0; i--) { | |||
var tag = tags[i]; | |||
var scale = fallLength / (fallLength + tag.z); | |||
var tagX = tag.x * scale + canvas[0].width / 2; | |||
var tagY = tag.y * scale + canvas[0].height / 2; | |||
ctx.font = Math.floor(14 + 10 * scale) + 'px sans-serif'; | |||
var metrics = ctx.measureText(tag.text); | |||
var width = metrics.width; | |||
var height = Math.floor(14 + 10 * scale); | |||
if (x >= tagX - width/2 && x <= tagX + width/2 && | |||
y >= tagY - height/2 && y <= tagY + height/2) { | |||
overTag = true; | |||
break; | |||
} | |||
} | |||
canvas.css('cursor', overTag ? 'pointer' : 'default'); | |||
}); | |||
}); | }); | ||
})(); | })(); | ||
Revision as of 09:45, 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 for Main Page
* Auto-rotates continuously, very visible
*/
(function() {
// Only run on Main Page
if (mw.config.get('wgPageName') !== 'Main_Page') {
return;
}
$(document).ready(function() {
var placeholder = document.getElementById('ceo-tagcloud-placeholder');
if (!placeholder) return;
// Topics
var topics = [
{ text: 'Satya Nadella', url: '/wiki/Satya_Nadella' },
{ text: 'Tim Cook', url: '/wiki/Tim_Cook' },
{ text: 'Elon Musk', url: '/wiki/Elon_Musk' },
{ text: 'Mark Zuckerberg', url: '/wiki/Mark_Zuckerberg' },
{ text: 'Sundar Pichai', url: '/wiki/Sundar_Pichai' },
{ text: 'Andy Jassy', url: '/wiki/Andy_Jassy' },
{ text: 'Jensen Huang', url: '/wiki/Jensen_Huang' },
{ text: 'Lisa Su', url: '/wiki/Lisa_Su' },
{ text: 'Mary Barra', url: '/wiki/Mary_Barra' },
{ text: 'Jamie Dimon', url: '/wiki/Jamie_Dimon' },
{ text: 'Microsoft', url: '/wiki/Microsoft' },
{ text: 'Apple', url: '/wiki/Apple_Inc.' },
{ text: 'Amazon', url: '/wiki/Amazon' },
{ text: 'Google', url: '/wiki/Google' },
{ text: 'Tesla', url: '/wiki/Tesla' },
{ text: 'Leadership', url: '/wiki/Category:Chief_executive_officers' },
{ text: 'Innovation', url: '/wiki/Category:Business_strategies' },
{ text: 'Technology', url: '/wiki/Category:Companies' },
{ text: 'Strategy', url: '/wiki/Category:Business_strategies' },
{ text: 'Cloud Computing', url: '/wiki/Category:Industry_analysis' }
];
// Create container
var container = $('<div>').css({
'background': 'linear-gradient(135deg, #0a1929 0%, #1a2942 50%, #0d2744 100%)',
'padding': '40px 20px',
'border-radius': '12px',
'box-shadow': '0 15px 40px rgba(0,0,0,0.4)',
'min-height': '400px',
'position': 'relative',
'overflow': 'hidden'
});
// Title
var title = $('<div>').text('TRENDING TOPICS').css({
'color': 'white',
'font-size': '1.4em',
'font-weight': '700',
'text-align': 'center',
'margin-bottom': '30px',
'text-shadow': '0 4px 10px rgba(0,0,0,0.5)'
});
container.append(title);
// Canvas for 3D cloud
var canvas = $('<canvas>').attr({
'id': 'tagcloud3d-canvas',
'width': '800',
'height': '400'
}).css({
'display': 'block',
'margin': '0 auto',
'max-width': '100%'
});
container.append(canvas);
placeholder.appendChild(container[0]);
// 3D Tag Cloud Implementation
var ctx = canvas[0].getContext('2d');
var tags = [];
var radius = 150;
var fallLength = 500;
var angleX = 0;
var angleY = 0;
var speedX = 0.01; // Auto-rotation speed
var speedY = 0.015;
// Initialize tags in 3D space
topics.forEach(function(topic, i) {
var phi = Math.acos(-1 + (2 * i) / topics.length);
var theta = Math.sqrt(topics.length * Math.PI) * phi;
tags.push({
text: topic.text,
url: topic.url,
x: radius * Math.sin(phi) * Math.cos(theta),
y: radius * Math.cos(phi),
z: radius * Math.sin(phi) * Math.sin(theta),
originalX: radius * Math.sin(phi) * Math.cos(theta),
originalY: radius * Math.cos(phi),
originalZ: radius * Math.sin(phi) * Math.sin(theta)
});
});
// Rotation functions
function rotateX(x, y, z, angle) {
var cos = Math.cos(angle);
var sin = Math.sin(angle);
return {
x: x,
y: y * cos - z * sin,
z: y * sin + z * cos
};
}
function rotateY(x, y, z, angle) {
var cos = Math.cos(angle);
var sin = Math.sin(angle);
return {
x: x * cos + z * sin,
y: y,
z: -x * sin + z * cos
};
}
// Animation loop
function animate() {
// Clear canvas
ctx.clearRect(0, 0, canvas[0].width, canvas[0].height);
// Auto-rotate
angleX += speedX;
angleY += speedY;
// Update and draw tags
tags.forEach(function(tag) {
// Apply rotations
var rotated = rotateX(tag.originalX, tag.originalY, tag.originalZ, angleX);
rotated = rotateY(rotated.x, rotated.y, rotated.z, angleY);
tag.x = rotated.x;
tag.y = rotated.y;
tag.z = rotated.z;
});
// Sort by z-depth (back to front)
tags.sort(function(a, b) {
return a.z - b.z;
});
// Draw tags
tags.forEach(function(tag) {
var scale = fallLength / (fallLength + tag.z);
var x = tag.x * scale + canvas[0].width / 2;
var y = tag.y * scale + canvas[0].height / 2;
var alpha = (tag.z + radius) / (2 * radius);
alpha = Math.max(0.3, Math.min(1, alpha));
// Font size based on depth
var fontSize = Math.floor(14 + 10 * scale);
ctx.save();
ctx.font = fontSize + 'px sans-serif, "Helvetica Neue", Helvetica, Arial';
ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 5;
ctx.fillText(tag.text, x, y);
ctx.restore();
});
requestAnimationFrame(animate);
}
// Start animation
animate();
// Make tags clickable
canvas.on('click', function(e) {
var rect = canvas[0].getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
// Check if click is near any tag
for (var i = tags.length - 1; i >= 0; i--) {
var tag = tags[i];
var scale = fallLength / (fallLength + tag.z);
var tagX = tag.x * scale + canvas[0].width / 2;
var tagY = tag.y * scale + canvas[0].height / 2;
ctx.font = Math.floor(14 + 10 * scale) + 'px sans-serif';
var metrics = ctx.measureText(tag.text);
var width = metrics.width;
var height = Math.floor(14 + 10 * scale);
if (x >= tagX - width/2 && x <= tagX + width/2 &&
y >= tagY - height/2 && y <= tagY + height/2) {
window.location.href = tag.url;
break;
}
}
});
// Change cursor on hover
canvas.on('mousemove', function(e) {
var rect = canvas[0].getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
var overTag = false;
for (var i = tags.length - 1; i >= 0; i--) {
var tag = tags[i];
var scale = fallLength / (fallLength + tag.z);
var tagX = tag.x * scale + canvas[0].width / 2;
var tagY = tag.y * scale + canvas[0].height / 2;
ctx.font = Math.floor(14 + 10 * scale) + 'px sans-serif';
var metrics = ctx.measureText(tag.text);
var width = metrics.width;
var height = Math.floor(14 + 10 * scale);
if (x >= tagX - width/2 && x <= tagX + width/2 &&
y >= tagY - height/2 && y <= tagY + height/2) {
overTag = true;
break;
}
}
canvas.css('cursor', overTag ? 'pointer' : 'default');
});
});
})();