Clown Mode

🤡 Spinning images, rainbow chaos, deep overlapping explosions. Single Shadow DOM overlay toggle + keyboard fallback to resist freezing.

目前為 2025-08-03 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Clown Mode
// @namespace    http://tampermonkey.net/
// @version      2.7
// @description  🤡 Spinning images, rainbow chaos, deep overlapping explosions. Single Shadow DOM overlay toggle + keyboard fallback to resist freezing.
// @author       Copilot
// @match        *://*/*
// @grant        none
// @run-at       document-idle
// @license      MIT https://opensource.org/licenses/MIT
// ==/UserScript==

(function () {
    'use strict';

    const EMOJI = '🤡';
    const EXPLOSION = '💥';
    let clownified = false;
    const STYLE_ID = 'clownModeStyle';
    let emojiRainInterval;
    let explosionTimeout;
    let currentExplosions = 0;
    const maxConcurrent = 3;

    // ---- inject global styles for clown effects ----
    function injectStyle() {
        if (document.getElementById(STYLE_ID)) return;
        const style = document.createElement('style');
        style.id = STYLE_ID;
        style.textContent = `
            @import url('https://fonts.googleapis.com/css2?family=Rubik+Mono+One&display=swap');

            .clown-mode img {
                animation: spin 5s linear infinite;
                border: 3px dashed magenta !important;
            }
            @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

            .clown-mode * {
                font-family: 'Rubik Mono One', cursive !important;
                animation: rainbowText 3s linear infinite;
            }
            @keyframes rainbowText {
                0% { color: red; }
                25% { color: orange; }
                50% { color: yellow; }
                75% { color: green; }
                100% { color: blue; }
            }

            @keyframes fall {
                to { top: ${window.innerHeight}px; opacity: 0; transform: rotate(720deg); }
            }

            @keyframes pop {
                0% { transform: scale(0.5); opacity: 1; }
                40% { transform: scale(1.8); }
                100% { transform: scale(2.5); opacity: 0; }
            }

            .explosion-wrapper {
                position: fixed;
                pointer-events: none;
                z-index: 1000000;
                user-select: none;
                display: flex;
                align-items: center;
                justify-content: center;
                transform: translate(-50%, -50%);
            }

            .explosion-bg {
                position: absolute;
                border-radius: 50%;
                filter: blur(35px);
                opacity: 0.7;
                mix-blend-mode: screen;
                pointer-events: none;
            }

            .explosion-emoji {
                animation: pop 1s ease-out forwards;
                font-weight: bold;
                text-shadow:
                    0 0 40px rgba(255, 80, 80, 1),
                    0 0 80px rgba(255, 160, 0, 0.9),
                    0 0 120px rgba(255, 0, 255, 0.8);
            }

            .clown-mode .clownify-fallback {
                position: fixed;
            }
        `;
        document.head.appendChild(style);
    }

    // ---- clown visuals ----
    function spawnClowns(batchSize = 30) {
        for (let i = 0; i < batchSize; i++) {
            const clown = document.createElement('div');
            clown.textContent = EMOJI;
            clown.style.position = 'fixed';
            clown.style.left = `${Math.random() * window.innerWidth}px`;
            clown.style.top = `-50px`;
            clown.style.fontSize = '24px';
            clown.style.zIndex = '999999';
            clown.style.animation = 'fall 4s linear forwards';
            clown.style.pointerEvents = 'none';
            document.body.appendChild(clown);
            setTimeout(() => clown.remove(), 5000);
        }
    }

    function spawnExplosion() {
        if (!clownified || currentExplosions >= maxConcurrent) return;
        currentExplosions++;
        const wrapper = document.createElement('div');
        wrapper.className = 'explosion-wrapper';

        const size = 140 + Math.random() * 160; // large explosion
        const left = Math.random() * window.innerWidth;
        const top = Math.random() * window.innerHeight;
        wrapper.style.left = `${left}px`;
        wrapper.style.top = `${top}px`;

        const bg = document.createElement('div');
        bg.className = 'explosion-bg';
        const colors = [
            'rgba(220,30,100,0.85)',
            'rgba(255,60,10,0.85)',
            'rgba(130,10,220,0.85)',
            'rgba(255,140,0,0.85)',
            'rgba(200,0,255,0.85)'
        ];
        const color = colors[Math.floor(Math.random() * colors.length)];
        bg.style.width = `${size * 1.8}px`;
        bg.style.height = `${size * 1.8}px`;
        bg.style.left = '50%';
        bg.style.top = '50%';
        bg.style.transform = 'translate(-50%, -50%)';
        bg.style.background = `radial-gradient(circle at 50% 50%, ${color} 0%, transparent 85%)`;

        const emoji = document.createElement('div');
        emoji.className = 'explosion-emoji';
        emoji.textContent = EXPLOSION;
        emoji.style.fontSize = `${size}px`;
        emoji.style.position = 'relative';

        wrapper.appendChild(bg);
        wrapper.appendChild(emoji);
        document.body.appendChild(wrapper);

        setTimeout(() => {
            wrapper.remove();
            currentExplosions = Math.max(0, currentExplosions - 1);
        }, 1000);
    }

    function scheduleNextExplosion() {
        if (!clownified) return;
        const delay = 30 + Math.random() * 30; // 30–60ms for high frequency with slight overlap
        explosionTimeout = setTimeout(() => {
            spawnExplosion();
            scheduleNextExplosion();
        }, delay);
    }

    function startClownEffects() {
        document.body.classList.add('clown-mode');
        emojiRainInterval = setInterval(() => spawnClowns(30), 300);
        scheduleNextExplosion();
    }

    function stopClownEffects() {
        document.body.classList.remove('clown-mode');
        clearInterval(emojiRainInterval);
        clearTimeout(explosionTimeout);
        currentExplosions = 0;
        document.querySelectorAll('*').forEach(el => {
            el.style.animation = '';
        });
    }

    function toggleClown() {
        clownified = !clownified;
        if (clownified) startClownEffects();
        else stopClownEffects();
        updateButtonState();
        // kickoff burst when activating
        if (clownified) {
            for (let i = 0; i < 4; i++) {
                setTimeout(spawnExplosion, i * 80);
            }
        }
    }

    // ---- overlay button in Shadow DOM ----
    const BUTTON_ID = 'clown-toggle-shadow-btn';
    const CONTAINER_ID = 'clown-toggle-shadow-container';

    function createToggleOverlay() {
        // remove existing container if any (to ensure only one)
        const existing = document.getElementById(CONTAINER_ID);
        if (existing) existing.remove();

        const container = document.createElement('div');
        container.id = CONTAINER_ID;
        container.style.position = 'fixed';
        container.style.bottom = '14px';
        container.style.left = '14px';
        container.style.zIndex = '2147483647'; // max
        container.style.pointerEvents = 'auto';

        // attach shadow root to isolate
        const shadow = container.attachShadow({ mode: 'open' });

        // base styles and button
        const wrapper = document.createElement('div');
        wrapper.style.position = 'relative';
        wrapper.style.display = 'flex';

        const btn = document.createElement('button');
        btn.id = BUTTON_ID;
        btn.textContent = EMOJI;
        btn.setAttribute('title', 'Toggle Clown Mode (Shift+Alt+C)');
        btn.style.all = 'initial';
        btn.style.cursor = 'pointer';
        btn.style.fontSize = '32px';
        btn.style.width = '60px';
        btn.style.height = '60px';
        btn.style.borderRadius = '50%';
        btn.style.border = 'none';
        btn.style.display = 'flex';
        btn.style.alignItems = 'center';
        btn.style.justifyContent = 'center';
        btn.style.position = 'relative';
        btn.style.background = 'linear-gradient(135deg,#ff88ee,#88ddff)';
        btn.style.color = 'white';
        btn.style.boxShadow = '0 0 20px rgba(255,0,200,0.9)';
        btn.style.transition = 'transform .15s, filter .2s';
        btn.style.userSelect = 'none';

        const pulse = document.createElement('div');
        pulse.style.position = 'absolute';
        pulse.style.inset = '0';
        pulse.style.borderRadius = '50%';
        pulse.style.boxShadow = '0 0 25px rgba(255,255,255,0.6)';
        pulse.style.animation = 'pulse 1s infinite';
        pulse.style.pointerEvents = 'none';

        const styleTag = document.createElement('style');
        styleTag.textContent = `
            @keyframes pulse {
                0% { transform: scale(1); opacity: 1; }
                50% { transform: scale(1.1); opacity: 0.7; }
                100% { transform: scale(1); opacity: 1; }
            }
            button.active {
                filter: brightness(1.4);
                transform: scale(1.05);
            }
        `;

        btn.appendChild(pulse);
        wrapper.appendChild(btn);
        shadow.appendChild(styleTag);
        shadow.appendChild(wrapper);
        document.documentElement.appendChild(container);

        btn.addEventListener('click', (e) => {
            e.stopPropagation();
            toggleClown();
        });

        // resilience: if removed by something, re-add after short delay
        const mo = new MutationObserver(() => {
            if (!document.getElementById(CONTAINER_ID)) {
                setTimeout(createToggleOverlay, 100);
            }
        });
        mo.observe(document.documentElement, { childList: true });

        updateButtonState();
    }

    function updateButtonState() {
        const container = document.getElementById(CONTAINER_ID);
        if (!container) return;
        const shadow = container.shadowRoot;
        if (!shadow) return;
        const btn = shadow.getElementById(BUTTON_ID);
        if (!btn) return;
        if (clownified) btn.classList.add('active');
        else btn.classList.remove('active');
    }

    // ---- keyboard fallback ----
    function setupShortcut() {
        window.addEventListener('keydown', (e) => {
            if (e.shiftKey && e.altKey && e.code === 'KeyC') {
                toggleClown();
            }
        });
    }

    // ---- init ----
    window.addEventListener('load', () => {
        injectStyle();
        createToggleOverlay();
        setupShortcut();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址