Jump to content

MediaWiki:Common.js: Difference between revisions

The comprehensive free global encyclopedia of CEOs, corporate leadership, and business excellence
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 Interactive Animation */
/* 3D Tag Cloud - Dynamic Builder */
(function() {
(function() {
     if (typeof window.TagCloudInitialized !== 'undefined') return;
     if (typeof window.CEOTagCloudInit !== 'undefined') return;
     window.TagCloudInitialized = true;
     window.CEOTagCloudInit = true;


     function initTagCloud() {
     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 = container.getElementsByClassName('tag-item');
         tags.forEach(function(tag) {
        if (tags.length === 0) return;
            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 = 180;
        // 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 = 1;
         var lasta = 0.5;
         var lastb = 1;
         var lastb = 0.5;
        var distr = true;
         var tspeed = 2;
         var tspeed = 2;
         var size = 250;
         var size = 200;
         var mouseX = 0;
         var mouseX = 0;
         var mouseY = 0;
         var mouseY = 0;
         var howElliptical = 1;
          
        var aA = null;
         var sa, ca, sb, cb, sc, cc;
         var oDiv = container;


         // Position tags in 3D sphere
         // Initialize positions
        var i = 0;
         for (var i = 0; i < elements.length; i++) {
        var oTag = null;
             var oTag = {};
       
             oTag.offsetWidth = elements[i].offsetWidth;
         for (i = 0; i < tags.length; i++) {
             oTag.offsetHeight = elements[i].offsetHeight;
             oTag = {};
             oTag.offsetWidth = tags[i].offsetWidth;
             oTag.offsetHeight = tags[i].offsetHeight;
             mcList.push(oTag);
             mcList.push(oTag);
         }
         }


         sineCosine(0, 0, 0);
         sineCosine(0, 0, 0);
         positionAll();
         positionAll();


         // Auto-rotate
         setInterval(update, 30);
        var autoRotateTimer = setInterval(update, 30);


         function update() {
         function update() {
             var a;
             var a, b;
            var 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) {
                // Gentle auto-rotation when idle
                 a = 0.3;
                 a = 0.3;
                 b = 0.3;
                 b = 0.3;
             }
             }


            var c = 0;
             sineCosine(a, b, 0);
             sineCosine(a, b, c);
              
              
             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;


                var rx3 = rx2 * cc + ry2 * (-sc);
                 mcList[i].cx = rx2;
                var ry3 = rx2 * sc + ry2 * cc;
                 mcList[i].cy = ry2;
                var rz3 = rz2;
                 mcList[i].cz = rz2;
 
                 mcList[i].cx = rx3;
                 mcList[i].cy = ry3;
                 mcList[i].cz = rz3;
 
                var per = 350 / (350 + rz3);


                 mcList[i].x = rx3 * per;
                var per = 350 / (350 + rz2);
                 mcList[i].y = ry3 * per;
                 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 i = 0;
             var aTmp = [];
             var aTmp = [];
 
             for (var i = 0; i < elements.length; i++) {
             for (i = 0; i < tags.length; i++) {
                 aTmp.push(elements[i]);
                 aTmp.push(tags[i]);
                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;
                    return -1;
                 else if (vItem1.cz < vItem2.cz) return 1;
                 } else if (vItem1.cz < vItem2.cz) {
                 else return 0;
                    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 = 0;
             var phi, theta, max = mcList.length;
            var theta = 0;
            var max = mcList.length;
            var aTmp = [];
            var oFragment = document.createDocumentFragment();


             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);


                 tags[i].style.left = mcList[i].cx + oDiv.offsetWidth / 2 - mcList[i].offsetWidth / 2 + 'px';
                 elements[i].style.left = mcList[i].cx + container.offsetWidth / 2 - mcList[i].offsetWidth / 2 + 'px';
                 tags[i].style.top = mcList[i].cy + oDiv.offsetHeight / 2 - mcList[i].offsetHeight / 2 + 'px';
                 elements[i].style.top = mcList[i].cy + container.offsetHeight / 2 - mcList[i].offsetHeight / 2 + 'px';
             }
             }
         }
         }


         function doPosition() {
         function doPosition() {
             var l = oDiv.offsetWidth / 2;
             var l = container.offsetWidth / 2;
             var t = oDiv.offsetHeight / 2;
             var t = container.offsetHeight / 2;
              
              
             for (var i = 0; i < mcList.length; i++) {
             for (var i = 0; i < mcList.length; i++) {
                 var item = tags[i];
                 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.style.fontSize = Math.ceil(12 * mc.scale / 2) + 8 + 'px';
                 var baseSize = parseFloat(item.getAttribute('data-weight')) / 10;
                 item.style.filter = 'alpha(opacity=' + 100 * mc.alpha + ')';
                 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/Touch interaction
         // Mouse interaction
         var containerElement = document.getElementById('tagcloud-container');
         var containerElem = document.getElementById('tagcloud-container');
          
         containerElem.addEventListener('mouseover', function() {
        containerElement.addEventListener('mouseover', function() {
            active = true;
        });
 
        containerElement.addEventListener('mouseout', function() {
            active = false;
        });
 
        containerElement.addEventListener('mousemove', function(ev) {
            var rect = containerElement.getBoundingClientRect();
            mouseX = ev.clientX - rect.left - containerElement.offsetWidth / 2;
            mouseY = ev.clientY - rect.top - containerElement.offsetHeight / 2;
        });
 
        // Touch support
        containerElement.addEventListener('touchstart', function() {
             active = true;
             active = true;
         });
         });


         containerElement.addEventListener('touchend', function() {
         containerElem.addEventListener('mouseout', function() {
             active = false;
             active = false;
         });
         });


         containerElement.addEventListener('touchmove', function(ev) {
         containerElem.addEventListener('mousemove', function(ev) {
            ev.preventDefault();
             var rect = containerElem.getBoundingClientRect();
             var rect = containerElement.getBoundingClientRect();
             mouseX = ev.clientX - rect.left - containerElem.offsetWidth / 2;
             var touch = ev.touches[0];
             mouseY = ev.clientY - rect.top - containerElem.offsetHeight / 2;
            mouseX = touch.clientX - rect.left - containerElement.offsetWidth / 2;
             mouseY = touch.clientY - rect.top - containerElement.offsetHeight / 2;
         });
         });
     }
     }


    // Initialize when DOM is ready
     if (document.readyState === 'loading') {
     if (document.readyState === 'loading') {
         document.addEventListener('DOMContentLoaded', initTagCloud);
         document.addEventListener('DOMContentLoaded', buildAndInitTagCloud);
     } else {
     } else {
         initTagCloud();
         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();
    }
})();