Jump to content

MediaWiki:Common.js

The comprehensive free global encyclopedia of CEOs, corporate leadership, and business excellence
Revision as of 09:45, 20 October 2025 by Maintenance script (talk | contribs) (Fixed 3D tag cloud - now auto-rotates continuously, uses Canvas for visibility, clickable tags, proper depth sorting)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
 * 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');
        });
    });
})();