Page Roulette

Bored? Click the dice and discover a random interesting website

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Page Roulette
// @namespace    http://tampermonkey.net/
// @version      11.5
// @description  Bored? Click the dice and discover a random interesting website
// @author       Mustafa Hakan
// @icon https://img.icons8.com/fluency/48/maintenance.png
// @match        *://*/*
// @grant        GM_openInTab
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    const SITES = [
        { n: 'This Is Sand', u: 'https://thisissand.com', d: 'Paint with sand' },
        { n: 'Silk', u: 'http://weavesilk.com', d: 'Interactive light drawing' },
        { n: 'Pointer Pointer', u: 'https://pointerpointer.com', d: 'Cursor tracking fun' },
        { n: 'Hacker Typer', u: 'https://hackertyper.com', d: 'Pretend to be a hacker' },
        { n: 'Scale of Universe', u: 'https://htwins.net/scale2/', d: 'Zoom from quarks to galaxies' },
        { n: 'Quick Draw', u: 'https://quickdraw.withgoogle.com', d: 'AI guesses your drawing' },
        { n: 'A Soft Murmur', u: 'https://asoftmurmur.com', d: 'Ambient sounds' },
        { n: 'Radio Garden', u: 'http://radio.garden', d: 'Explore world radios' },
        { n: 'Window Swap', u: 'https://window-swap.com', d: 'Peek through windows worldwide' },
        { n: 'Patatap', u: 'https://patatap.com', d: 'Visual sound toy' },
        { n: '2048', u: 'https://play2048.co', d: 'Merge number tiles' },
        { n: 'Little Alchemy', u: 'https://littlealchemy.com', d: 'Combine elements' },
        { n: 'Neal Fun', u: 'https://neal.fun', d: 'Oddly satisfying experiments' },
        { n: 'Rainy Mood', u: 'https://rainymood.com', d: 'Rain sounds' },
        { n: 'The Useless Web', u: 'https://theuselessweb.com', d: 'Random weird sites' },
        { n: 'Bored Panda', u: 'https://www.boredpanda.com', d: 'Funny & creative content' },
        { n: 'Zoom Quilt', u: 'https://zoomquilt.org', d: 'Infinite zoom illusion' },
        { n: 'Staggering Beauty', u: 'https://staggeringbeauty.com', d: 'Wiggle it!' },
        { n: 'Cat Bounce', u: 'https://cat-bounce.com', d: 'Bouncing cats' },
        { n: 'Remove BG', u: 'https://www.remove.bg', d: 'Remove image backgrounds' },
        { n: 'Photopea', u: 'https://www.photopea.com', d: 'Online Photoshop' },
        { n: 'Every Noise', u: 'https://everynoise.com', d: 'All music genres' },
        { n: 'Flight Radar', u: 'https://www.flightradar24.com', d: 'Live air traffic' },
        { n: 'NASA APOD', u: 'https://apod.nasa.gov/apod/', d: 'Daily astronomy picture' },
        { n: 'GeoGuessr', u: 'https://www.geoguessr.com/free', d: 'Guess the location' },
        { n: 'Coolors', u: 'https://coolors.co', d: 'Color palette generator' },
        { n: 'Poolside FM', u: 'https://poolside.fm', d: 'Retro summer radio' },
        { n: 'This Person Does Not Exist', u: 'https://thispersondoesnotexist.com', d: 'AI‑generated faces' },
        { n: 'Spend Elon Money', u: 'https://neal.fun/spend/', d: 'Spend billions' },
        { n: 'Internet Archive', u: 'https://archive.org', d: 'Digital library' }
    ];

    let spinning = false;

    GM_addStyle(`
        #r-trigger {
            position: fixed;
            bottom: 24px;
            right: 24px;
            width: 48px;
            height: 48px;
            background-color: #2a2a2a;
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect x='5' y='5' width='90' height='90' rx='20' fill='%23ffffff'/%3E%3Ccircle cx='30' cy='30' r='10' fill='%23000'/%3E%3Ccircle cx='70' cy='70' r='10' fill='%23000'/%3E%3C/svg%3E");
            background-size: 36px;
            background-repeat: no-repeat;
            background-position: center;
            border: 1px solid #555;
            border-radius: 12px;
            cursor: pointer;
            z-index: 2147483644;
            box-shadow: 0 4px 12px rgba(0,0,0,0.5);
            transition: transform 0.2s ease, border-color 0.2s, box-shadow 0.2s;
        }
        #r-trigger:hover {
            transform: scale(1.08);
            border-color: #888;
            box-shadow: 0 6px 18px rgba(0,0,0,0.6);
        }
        #r-trigger:active {
            transform: scale(0.96);
            transition: transform 0.1s;
        }
        #r-panel {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #1e1e1e;
            border: 1px solid #444;
            border-radius: 16px;
            padding: 24px;
            z-index: 2147483646;
            font-family: system-ui, -apple-system, sans-serif;
            color: #ddd;
            min-width: 320px;
            text-align: center;
            box-shadow: 0 20px 50px rgba(0,0,0,0.8);
            animation: rFadeIn 0.25s ease;
            user-select: none;
        }
        @keyframes rFadeIn {
            from { opacity: 0; transform: translate(-50%, -48%); }
            to { opacity: 1; transform: translate(-50%, -50%); }
        }
        @keyframes rPop {
            0%,100% { transform: scale(1); }
            50% { transform: scale(1.04); }
        }
        #r-panel .panel-title {
            font-weight: 600;
            font-size: 17px;
            margin-bottom: 12px;
            color: #ccc;
        }
        #r-display {
            min-height: 60px;
            padding: 12px;
            background: rgba(255,255,255,0.03);
            border-radius: 12px;
            margin: 10px 0;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            transition: background 0.2s;
        }
        #r-display .placeholder {
            color: #888;
        }
        #r-spin, #r-go, #r-close {
            width: 100%;
            padding: 12px;
            border-radius: 10px;
            border: 1px solid #555;
            background: #333;
            color: #eee;
            font-size: 15px;
            cursor: pointer;
            margin: 6px 0;
            transition: background 0.2s, border-color 0.2s, color 0.2s;
        }
        #r-spin:hover, #r-go:hover, #r-close:hover {
            background: #444;
            border-color: #777;
        }
        #r-spin:active, #r-go:active, #r-close:active {
            background: #2a2a2a;
        }
        #r-go {
            background: #444;
            display: none;
        }
        #r-close {
            background: transparent;
            border-color: #444;
            color: #888;
        }
        #r-close:hover {
            color: #ccc;
            background: rgba(255,255,255,0.05);
        }
    `);

    function spin() {
        if (spinning) return;
        spinning = true;
        const display = document.getElementById('r-display');
        const goBtn = document.getElementById('r-go');

        let count = 0;
        const interval = setInterval(() => {
            const s = SITES[Math.floor(Math.random() * SITES.length)];
            display.innerHTML = `<div style="font-size:28px;">${s.n}</div><div style="color:#aaa;font-size:12px;">${s.d}</div>`;
            count++;
            if (count >= 25) {
                clearInterval(interval);
                const final = SITES[Math.floor(Math.random() * SITES.length)];
                display.innerHTML = `<div style="font-size:32px;">${final.n}</div><div style="color:#aaa;font-size:12px;">${final.d}</div>`;
                display.style.animation = 'rPop 0.4s';
                setTimeout(() => display.style.animation = '', 400);
                goBtn.style.display = 'block';
                goBtn.onclick = () => GM_openInTab(final.u, { active: true });
                spinning = false;
            }
        }, 70);
    }

    function createPanel() {
        const existing = document.getElementById('r-panel');
        if (existing) existing.remove();

        const panel = document.createElement('div');
        panel.id = 'r-panel';
        panel.innerHTML = `
            <div class="panel-title">🎲 Page Roulette</div>
            <div id="r-display"><div class="placeholder">Ready to spin</div></div>
            <button id="r-spin">Spin</button>
            <button id="r-go">Go!</button>
            <button id="r-close">Close</button>
        `;
        document.body.appendChild(panel);

        document.getElementById('r-spin').onclick = spin;
        document.getElementById('r-close').onclick = () => panel.remove();
    }

    function createTrigger() {
        if (document.getElementById('r-trigger')) return;
        const trigger = document.createElement('div');
        trigger.id = 'r-trigger';
        trigger.title = 'Page Roulette (Ctrl+Shift+R)';
        trigger.addEventListener('click', () => {
            if (document.getElementById('r-panel')) {
                document.getElementById('r-panel').remove();
            } else {
                createPanel();
            }
        });
        document.body.appendChild(trigger);
    }

    document.addEventListener('keydown', e => {
        if (e.ctrlKey && e.shiftKey && e.key === 'R') {
            e.preventDefault();
            if (document.getElementById('r-panel')) {
                document.getElementById('r-panel').remove();
            } else {
                createPanel();
            }
        }
    });

    setTimeout(createTrigger, 800);
})();