// ==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();
});
})();