Keyboard Wizard - Text Effects

Effect Color Trace Sound

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(Tôi đã có Trình quản lý tập lệnh người dùng, hãy cài đặt nó!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Keyboard Wizard - Text Effects
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  Effect Color Trace Sound
// @author       Mustafa Hakan
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Ayarlar
    const CFG = {
        effect: GM_getValue('kb_effect', 'fire'),
        hidePass: GM_getValue('kb_hidepass', true),
        sound: GM_getValue('kb_sound', true),
        trail: GM_getValue('kb_trail', true),
        particles: GM_getValue('kb_particles', true)
    };

    const EFFECTS = {
        fire: { name: '🔥 Ateş', color: '#ff4500', glow: '#ff8c00', trail: ['🔥','✨','💥'], sound: 'crackle' },
        ice: { name: '❄️ Buz', color: '#00d4ff', glow: '#87ceeb', trail: ['❄️','💎','✨'], sound: 'chime' },
        neon: { name: '💜 Neon', color: '#ff00ff', glow: '#ff69b4', trail: ['💜','💗','✨'], sound: 'buzz' },
        matrix: { name: '💚 Matrix', color: '#00ff41', glow: '#00cc33', trail: ['💚','⌨️','💻'], sound: 'type' },
        gold: { name: '👑 Altın', color: '#ffd700', glow: '#ffec8b', trail: ['👑','💰','✨'], sound: 'coin' },
        rainbow: { name: '🌈 Gökkuşağı', color: 'rainbow', glow: '#fff', trail: ['🌈','🎨','✨'], sound: 'magic' },
        shadow: { name: '🌑 Gölge', color: '#333', glow: '#000', trail: ['🌑','🖤','💨'], sound: 'whisper' },
        magic: { name: '🔮 Sihir', color: '#a855f7', glow: '#c084fc', trail: ['🔮','⭐','💫'], sound: 'sparkle' }
    };

    let activeEffect = EFFECTS[CFG.effect] || EFFECTS.fire;
    let audioCtx = null;
    let styleElement = null;

    // ---------- TEK STİL ETİKETİ ----------
    function updateStyles() {
        if (!styleElement) {
            styleElement = document.createElement('style');
            styleElement.id = 'kb-main-style';
            document.head.appendChild(styleElement);
        }
        const color = activeEffect.color === 'rainbow' ? '#fff' : activeEffect.color;
        const glow = activeEffect.glow;
        styleElement.textContent = `
            input:focus, textarea:focus, [contenteditable="true"]:focus {
                caret-color: ${color} !important;
                text-shadow: 0 0 5px ${glow} !important;
                transition: text-shadow 0.3s !important;
            }
            input[type="password"]:focus {
                letter-spacing: 3px !important;
                font-family: monospace !important;
            }
            ::selection {
                background: ${color}44 !important;
                color: ${color} !important;
            }
            ${activeEffect.color === 'rainbow' ? `
            .kb-rainbow-focus:focus {
                animation: kbRainbowText 2s linear infinite !important;
            }
            ` : ''}
            @keyframes kbSlideIn {
                from { opacity: 0; transform: translateX(20px); }
                to { opacity: 1; transform: translateX(0); }
            }
            @keyframes kbFloat {
                0%,100% { transform: translateY(0); }
                50% { transform: translateY(-6px); }
            }
            @keyframes kbRainbowText {
                0% { text-shadow: 0 0 5px #ff0000; }
                16% { text-shadow: 0 0 5px #ff7700; }
                33% { text-shadow: 0 0 5px #ffff00; }
                50% { text-shadow: 0 0 5px #00ff00; }
                66% { text-shadow: 0 0 5px #0077ff; }
                83% { text-shadow: 0 0 5px #8b00ff; }
                100% { text-shadow: 0 0 5px #ff0000; }
            }
        `;
    }

    // ---------- SES ----------
    function initAudio() {
        if (audioCtx) return;
        try {
            audioCtx = new (window.AudioContext || window.webkitAudioContext)();
            if (audioCtx.state === 'suspended') {
                const resume = () => {
                    audioCtx.resume();
                    document.removeEventListener('click', resume);
                    document.removeEventListener('keydown', resume);
                };
                document.addEventListener('click', resume);
                document.addEventListener('keydown', resume);
            }
        } catch(e) { /* sessizce başarısız */ }
    }

    function playSound(type) {
        if (!CFG.sound || !audioCtx || audioCtx.state !== 'running') return;
        try {
            const osc = audioCtx.createOscillator();
            const gain = audioCtx.createGain();
            gain.gain.setValueAtTime(0.02, audioCtx.currentTime);
            gain.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + 0.1);
            switch(type) {
                case 'crackle': osc.type = 'sawtooth'; osc.frequency.setValueAtTime(100 + Math.random()*200, audioCtx.currentTime); break;
                case 'chime': osc.type = 'sine'; osc.frequency.setValueAtTime(800 + Math.random()*400, audioCtx.currentTime); break;
                case 'buzz': osc.type = 'square'; osc.frequency.setValueAtTime(60 + Math.random()*30, audioCtx.currentTime); break;
                case 'type': osc.type = 'triangle'; osc.frequency.setValueAtTime(300 + Math.random()*200, audioCtx.currentTime); break;
                case 'coin': osc.type = 'sine'; osc.frequency.setValueAtTime(1000 + Math.random()*500, audioCtx.currentTime); break;
                case 'magic': osc.type = 'sine'; osc.frequency.setValueAtTime(400 + Math.random()*600, audioCtx.currentTime); osc.frequency.linearRampToValueAtTime(1200, audioCtx.currentTime + 0.1); break;
                case 'sparkle': osc.type = 'triangle'; osc.frequency.setValueAtTime(1500 + Math.random()*1000, audioCtx.currentTime); break;
                case 'whisper': osc.type = 'sine'; osc.frequency.setValueAtTime(80 + Math.random()*40, audioCtx.currentTime); gain.gain.setValueAtTime(0.01, audioCtx.currentTime); break;
                default: osc.type = 'sine'; osc.frequency.setValueAtTime(500, audioCtx.currentTime);
            }
            osc.connect(gain);
            gain.connect(audioCtx.destination);
            osc.start();
            osc.stop(audioCtx.currentTime + 0.1);
        } catch(e) {}
    }

    // ---------- İZ VE PARÇACIK ----------
    function spawnTrail(x, y) {
        if (!CFG.trail) return;
        const emoji = activeEffect.trail[Math.floor(Math.random() * activeEffect.trail.length)];
        const el = document.createElement('span');
        el.textContent = emoji;
        Object.assign(el.style, {
            position: 'fixed', left: x+'px', top: y+'px', pointerEvents: 'none',
            zIndex: '2147483647', fontSize: (12 + Math.random()*16)+'px',
            opacity: '1', transition: 'all 0.8s ease-out'
        });
        document.body.appendChild(el);
        requestAnimationFrame(() => {
            el.style.transform = `translate(${(Math.random()-0.5)*60}px, ${-30-Math.random()*40}px) rotate(${(Math.random()-0.5)*40}deg)`;
            el.style.opacity = '0';
        });
        setTimeout(() => el.remove(), 800);
    }

    function spawnParticle(x, y) {
        if (!CFG.particles || activeEffect.color !== 'rainbow') return;
        const colors = ['#ff0000','#ff7700','#ffff00','#00ff00','#0077ff','#8b00ff'];
        const color = colors[Math.floor(Math.random() * colors.length)];
        const particle = document.createElement('div');
        Object.assign(particle.style, {
            position: 'fixed', left: x+'px', top: y+'px', pointerEvents: 'none',
            zIndex: '2147483646', width: '6px', height: '6px', background: color,
            borderRadius: '50%', boxShadow: `0 0 10px ${color}, 0 0 20px ${color}`,
            transition: 'all 0.6s ease-out'
        });
        document.body.appendChild(particle);
        requestAnimationFrame(() => {
            particle.style.transform = `translate(${(Math.random()-0.5)*80}px, -${20+Math.random()*40}px) scale(0)`;
            particle.style.opacity = '0';
        });
        setTimeout(() => particle.remove(), 600);
    }

    // ---------- İMLEÇ POZİSYONU ----------
    function getCursorPosition() {
        try {
            const sel = window.getSelection();
            if (sel && sel.rangeCount > 0) {
                const rect = sel.getRangeAt(0).getBoundingClientRect();
                if (rect) return { x: rect.right, y: rect.top };
            }
        } catch(e) {}
        return null;
    }

    // ---------- TUŞ OLAYI ----------
    function onKeyDown(e) {
        if (e.target.closest('#kb-panel')) return;
        if (CFG.hidePass && e.target.type === 'password') {
            e.target.style.fontFamily = 'monospace';
            e.target.style.letterSpacing = '2px';
            e.target.style.textShadow = `0 0 8px ${activeEffect.glow}`;
        }
        const pos = getCursorPosition();
        if (pos && e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
            spawnTrail(pos.x, pos.y);
            if (CFG.sound) playSound(activeEffect.sound);
            spawnParticle(pos.x, pos.y);
        }
    }

    // ---------- PANEL VE BUTON (OLAY DELEGASYONU) ----------
    function createPanel() {
        if (document.getElementById('kb-panel')) return;

        const panel = document.createElement('div');
        panel.id = 'kb-panel';
        Object.assign(panel.style, {
            position: 'fixed', bottom: '100px', right: '30px', background: 'rgba(15,15,20,0.95)',
            border: `2px solid ${activeEffect.color}`, borderRadius: '16px', padding: '15px',
            zIndex: '2147483645', font: '13px system-ui', color: '#fff', minWidth: '220px',
            backdropFilter: 'blur(20px)', boxShadow: `0 15px 40px rgba(0,0,0,0.7), 0 0 20px ${activeEffect.glow}`,
            animation: 'kbSlideIn 0.3s ease-out'
        });

        // Başlık
        const title = document.createElement('div');
        title.textContent = '🧙 Klavye Büyücüsü';
        Object.assign(title.style, { fontWeight: '700', marginBottom: '10px', color: activeEffect.color });
        panel.appendChild(title);

        // Buton kabı (olay delegasyonu için)
        const btnContainer = document.createElement('div');
        btnContainer.style.cssText = 'display: flex; flex-direction: column; gap: 5px;';
        for (const [key, eff] of Object.entries(EFFECTS)) {
            const btn = document.createElement('button');
            btn.textContent = eff.name;
            btn.setAttribute('data-effect', key);
            Object.assign(btn.style, {
                padding: '10px', borderRadius: '10px', border: `1px solid ${CFG.effect === key ? eff.color : '#444'}`,
                background: CFG.effect === key ? eff.color+'22' : '#222', color: eff.color,
                cursor: 'pointer', transition: '0.2s', textAlign: 'left', font: '13px system-ui'
            });
            // Hover efektleri (döngü içinde ama sorunsuz)
            btn.addEventListener('mouseenter', () => { if (CFG.effect !== key) btn.style.background = '#333'; });
            btn.addEventListener('mouseleave', () => { if (CFG.effect !== key) btn.style.background = '#222'; });
            btnContainer.appendChild(btn);
        }
        panel.appendChild(btnContainer);

        // Olay delegasyonu: buton tıklamalarını yakala
        btnContainer.addEventListener('click', (e) => {
            const btn = e.target.closest('button[data-effect]');
            if (!btn) return;
            const newEffect = btn.dataset.effect;
            if (newEffect === CFG.effect) return;
            CFG.effect = newEffect;
            activeEffect = EFFECTS[newEffect];
            GM_setValue('kb_effect', newEffect);
            updateStyles();
            updateUI();
            panel.remove();
            createPanel(); // yeniden oluştur
        });

        // Ayarlar (checkbokslar)
        const opts = document.createElement('div');
        opts.style.cssText = 'margin-top: 10px; display: flex; flex-direction: column; gap: 6px; color: #aaa; font-size: 11px;';

        const createCheck = (label, cfgKey, storageKey) => {
            const labelEl = document.createElement('label');
            labelEl.style.cssText = 'display: flex; justify-content: space-between; align-items: center;';
            const input = document.createElement('input');
            input.type = 'checkbox';
            input.checked = CFG[cfgKey];
            input.addEventListener('change', (e) => {
                CFG[cfgKey] = e.target.checked;
                GM_setValue(storageKey, e.target.checked);
                if (storageKey === 'kb_sound' && e.target.checked && !audioCtx) initAudio();
            });
            labelEl.appendChild(document.createTextNode(label));
            labelEl.appendChild(input);
            return labelEl;
        };

        opts.appendChild(createCheck('🔒 Şifre Gizleme', 'hidePass', 'kb_hidepass'));
        opts.appendChild(createCheck('🔊 Ses Efekti', 'sound', 'kb_sound'));
        opts.appendChild(createCheck('✨ İz Efekti', 'trail', 'kb_trail'));
        opts.appendChild(createCheck('💫 Parçacık', 'particles', 'kb_particles'));
        panel.appendChild(opts);

        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'Kapat';
        Object.assign(closeBtn.style, {
            marginTop: '10px', width: '100%', padding: '8px', borderRadius: '8px',
            border: '1px solid #444', background: '#222', color: '#888', cursor: 'pointer'
        });
        closeBtn.addEventListener('click', () => panel.remove());
        panel.appendChild(closeBtn);

        document.body.appendChild(panel);
    }

    // ---------- TETİKLEYİCİ DÜĞME ----------
    function createTrigger() {
        if (document.getElementById('kb-trigger')) return;
        const btn = document.createElement('div');
        btn.id = 'kb-trigger';
        btn.textContent = '🧙';
        Object.assign(btn.style, {
            position: 'fixed', bottom: '30px', right: '30px', width: '45px', height: '45px',
            background: activeEffect.color === 'rainbow' ? '#333' : activeEffect.color+'22',
            border: `2px solid ${activeEffect.color}`, borderRadius: '50%',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: '22px', cursor: 'pointer', zIndex: '2147483644',
            boxShadow: `0 0 15px ${activeEffect.glow}`, transition: '0.3s',
            animation: 'kbFloat 3s ease-in-out infinite'
        });
        btn.addEventListener('click', () => {
            if (document.getElementById('kb-panel')) {
                document.getElementById('kb-panel').remove();
            } else {
                if (CFG.sound && !audioCtx) initAudio();
                createPanel();
            }
        });
        btn.addEventListener('mouseenter', () => { btn.style.transform = 'scale(1.15)'; });
        btn.addEventListener('mouseleave', () => { btn.style.transform = 'scale(1)'; });
        document.body.appendChild(btn);
    }

    // ---------- ARABİRİM GÜNCELLEME ----------
    function updateUI() {
        const trigger = document.getElementById('kb-trigger');
        if (trigger) {
            trigger.style.borderColor = activeEffect.color;
            trigger.style.boxShadow = `0 0 15px ${activeEffect.glow}`;
            trigger.style.background = activeEffect.color === 'rainbow' ? '#333' : activeEffect.color+'22';
        }
        const panel = document.getElementById('kb-panel');
        if (panel) {
            panel.style.borderColor = activeEffect.color;
            panel.style.boxShadow = `0 15px 40px rgba(0,0,0,0.7), 0 0 20px ${activeEffect.glow}`;
            const title = panel.querySelector('div:first-child');
            if (title) title.style.color = activeEffect.color;
            // Butonların border ve background güncellemesi (opsiyonel)
            const btns = panel.querySelectorAll('button[data-effect]');
            btns.forEach(btn => {
                const key = btn.dataset.effect;
                const eff = EFFECTS[key];
                if (key === CFG.effect) {
                    btn.style.border = `1px solid ${eff.color}`;
                    btn.style.background = eff.color+'22';
                } else {
                    btn.style.border = '1px solid #444';
                    btn.style.background = '#222';
                }
            });
        }
    }

    // ---------- GÖKKUŞAĞI ODAK YÖNETİMİ ----------
    function initRainbowFocus() {
        if (activeEffect.color !== 'rainbow') return;
        const addClass = (e) => {
            if (e.target.matches('input, textarea, [contenteditable="true"]')) {
                e.target.classList.add('kb-rainbow-focus');
            }
        };
        const removeClass = (e) => {
            if (e.target.matches('input, textarea, [contenteditable="true"]')) {
                e.target.classList.remove('kb-rainbow-focus');
            }
        };
        document.addEventListener('focusin', addClass);
        document.addEventListener('focusout', removeClass);
    }

    // ---------- BAŞLAT ----------
    function init() {
        updateStyles();
        createTrigger();
        document.addEventListener('keydown', onKeyDown);
        initRainbowFocus();
        if (CFG.sound) initAudio();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => setTimeout(init, 500));
    } else {
        setTimeout(init, 500);
    }
})();