Zebra Type Customizer

Animated BG, Text/Font changer, UI controls with maximize feature, diamond-locked premium colors/fonts.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

Advertisement:

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

Advertisement:

// ==UserScript==
// @name         Zebra Type Customizer
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Animated BG, Text/Font changer, UI controls with maximize feature, diamond-locked premium colors/fonts.
// @author       MyUserScripts
// @match        https://zebratype.org/*
// @match        https://zebratype.org/race
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const bgColors = [
        { val: "linear-gradient(90deg, #ff9a9e, #fad0c4)", name: "Peach" },
        { val: "linear-gradient(90deg, #a18cd1, #fbc2eb)", name: "Lavender" },
        { val: "linear-gradient(90deg, #84fab0, #8fd3f4)", name: "Seafoam" },
        { val: "linear-gradient(90deg, #ffecd2, #fcb69f)", name: "Sunset" },
        { val: "linear-gradient(90deg, #f093fb, #f5576c)", name: "Rose" },
        { val: "linear-gradient(90deg, #89f7fe, #66a6ff)", name: "Sky" },
        { val: "linear-gradient(90deg, #d4fc79, #96e6a1)", name: "Lime" },
        { val: "linear-gradient(90deg, #cfd9df, #e2ebf0)", name: "Silver" },
        { val: "linear-gradient(90deg, #ff9a9e, #fecfef)", name: "Cherry" },
        { val: "linear-gradient(90deg, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c, #bf953f)", name: "Gold", locked: true, special: true },
        { val: "linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet, red)", name: "Rainbow", locked: true, special: true }
    ];

    const textColors = [
        { val: "linear-gradient(90deg, #ff5e62, #ff9966)" }, { val: "linear-gradient(90deg, #f0f270, #ffcc00)" }, 
        { val: "linear-gradient(90deg, #00c6ff, #0072ff)" }, { val: "linear-gradient(90deg, #8e2de2, #4a00e0)" }, 
        { val: "linear-gradient(90deg, #ff00cc, #333399)" }, { val: "linear-gradient(90deg, #00ff9f, #00aa6b)" },
        { val: "linear-gradient(90deg, #ffffff, #aaaaaa)" }, { val: "linear-gradient(90deg, #bf953f, #fcf6ba)" },
        { val: "linear-gradient(90deg, red, violet)" }
    ];

    const fonts = [
        { name: "Arial", val: "Arial, sans-serif" },
        { name: "Courier", val: "'Courier New', Courier, monospace" },
        { name: "Impact", val: "Impact, Charcoal, sans-serif" },
        { name: "Verdana", val: "Verdana, Geneva, sans-serif" },
        { name: "Georgia", val: "Georgia, serif" },
        { name: "Comic Sans", val: "'Comic Sans MS', cursive" },
        { name: "Monoton", val: "'Monoton', cursive", locked: true },
        { name: "Bangers", val: "'Bangers', cursive", locked: true },
        { name: "Orbitron", val: "'Orbitron', sans-serif", locked: true }
    ];

    const style = document.createElement('style');
    style.innerHTML = `
        @keyframes scrollBG { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } }
        @keyframes glow { 0% { box-shadow: 0 0 5px #fff; } 50% { box-shadow: 0 0 20px #00d4ff; } 100% { box-shadow: 0 0 5px #fff; } }
        .zt-panel { position: fixed; top: 20px; right: 20px; width: 280px; background: rgba(0, 0, 0, 0.85); border: 2px solid transparent; border-radius: 20px; padding: 15px; z-index: 10000; color: #fff; font-family: 'Segoe UI', sans-serif; backdrop-filter: blur(10px); background-clip: padding-box; animation: glow 3s infinite alternate; }
        .zt-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; border-bottom: 1px solid rgba(255,255,255,0.2); padding-bottom: 8px; cursor: move; font-weight: bold; font-size: 13px; letter-spacing: 1px; }
        .zt-controls { cursor: pointer; display: flex; gap: 10px; font-weight: bold; align-items: center; color: #aaa; transition: 0.3s; }
        .zt-controls span:hover { color: #fff; transform: scale(1.2); }
        .zt-sec { margin-top: 10px; font-weight: 800; font-size: 9px; color: #00d4ff; text-transform: uppercase; margin-bottom: 8px; letter-spacing: 1.5px; }
        .zt-row { display: flex; flex-wrap: wrap; gap: 6px; }
        .zt-btn { width: 28px; height: 28px; border-radius: 10px; border: 2px solid rgba(255,255,255,0.1); cursor: pointer; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); position: relative; background-size: 200% 200% !important; animation: scrollBG 4s linear infinite; display: flex; align-items: center; justify-content: center; }
        .zt-btn:hover { transform: scale(1.1); border-color: #fff; box-shadow: 0 0 10px rgba(255,255,255,0.2); }
        .zt-font-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
        .zt-font-btn { position: relative; padding: 6px 4px; border-radius: 8px; background: rgba(255,255,255,0.05); color: #ddd; border: 1px solid rgba(255,255,255,0.1); cursor: pointer; text-align: center; font-size: 10px; transition: 0.3s; }
        .zt-font-btn:hover { background: rgba(0, 212, 255, 0.2); border-color: #00d4ff; color: #fff; }
        .diamond-mini { position: absolute; top: -7px; left: -7px; font-size: 9px; pointer-events: none; filter: drop-shadow(0 0 2px #fff); }
        .minimized { height: 35px; overflow: hidden; }
        .maximized { width: 95vw !important; height: 85vh !important; }
        .hidden { display: none; }
    `;
    document.head.appendChild(style);

    const settings = { bgGrad: 'linear-gradient(90deg, #000, #222)', textCol: 'transparent', font: 'Arial, sans-serif' };

    function playErrorSound() {
        try {
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            const audioCtx = new AudioContext();
            const osc = audioCtx.createOscillator();
            const gain = audioCtx.createGain();
            osc.connect(gain); gain.connect(audioCtx.destination);
            osc.type = 'sine'; osc.frequency.setValueAtTime(200, audioCtx.currentTime);
            gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
            osc.start(); osc.stop(audioCtx.currentTime + 0.1);
        } catch(e) { console.log("Audio skipped"); }
    }

    function updatePage() {
        document.body.style.background = settings.bgGrad;
        document.body.style.backgroundSize = "200% 100%";
        document.body.style.backgroundAttachment = "fixed";
        
        // Target specifically text inside main game elements or generally within panels
        // Using -webkit-background-clip: text to apply gradient to text
        const gameTextElements = document.querySelectorAll('.panel, .text-display, .game-text'); 
        gameTextElements.forEach(el => {
            el.style.backgroundImage = settings.textCol;
            el.style.webkitBackgroundClip = "text";
            el.style.backgroundClip = "text";
            el.style.color = "transparent";
            el.style.fontFamily = settings.font;
        });
    }

    const panel = document.createElement('div');
    panel.className = 'zt-panel';
    panel.innerHTML = `
        <div class="zt-header" id="zt-drag">
            <div>✨ Zebra Type Customizer</div>
            <div class="zt-controls"><span id="min">-</span><span id="max">□</span><span id="close">×</span></div>
        </div>
        <div id="zt-content"></div>
    `;

    document.body.appendChild(panel);

    document.getElementById('close').onclick = () => panel.remove();
    document.getElementById('min').onclick = () => {
        document.getElementById('zt-content').classList.toggle('hidden');
        panel.classList.toggle('minimized');
    };
    document.getElementById('max').onclick = () => panel.classList.toggle('maximized');

    const content = panel.querySelector('#zt-content');

    const bgSec = document.createElement('div'); bgSec.className = 'zt-sec'; bgSec.innerText = 'Background'; content.appendChild(bgSec);
    const bgRow = document.createElement('div'); bgRow.className = 'zt-row';
    bgColors.forEach(item => {
        const btn = document.createElement('button');
        btn.className = 'zt-btn';
        btn.style.background = item.val;
        if (item.locked) btn.innerHTML = `<span class="diamond-mini">💎</span>`;
        btn.onclick = () => {
            if (item.locked) { playErrorSound(); }
            else { settings.bgGrad = item.val; updatePage(); }
        };
        bgRow.appendChild(btn);
    });
    content.appendChild(bgRow);

    const txtSec = document.createElement('div'); txtSec.className = 'zt-sec'; txtSec.innerText = 'Text Color'; content.appendChild(txtSec);
    const txtRow = document.createElement('div'); txtRow.className = 'zt-row';
    textColors.forEach(item => {
        const btn = document.createElement('button');
        btn.className = 'zt-btn';
        btn.style.background = item.val;
        btn.onclick = () => { settings.textCol = item.val; updatePage(); };
        txtRow.appendChild(btn);
    });
    content.appendChild(txtRow);

    const fontSec = document.createElement('div'); fontSec.className = 'zt-sec'; fontSec.innerText = 'Fonts'; content.appendChild(fontSec);
    const fontGrid = document.createElement('div'); fontGrid.className = 'zt-font-grid';
    fonts.forEach(f => {
        const btn = document.createElement('button');
        btn.className = 'zt-font-btn';
        btn.style.fontFamily = f.val;
        if (f.locked) btn.innerHTML = `<span class="diamond-mini">💎</span>${f.name}`;
        else btn.innerText = f.name;
        btn.onclick = () => {
            if (f.locked) { playErrorSound(); }
            else { settings.font = f.val; updatePage(); }
        };
        fontGrid.appendChild(btn);
    });
    content.appendChild(fontGrid);

    let isDragging = false, offset = { x: 0, y: 0 };
    const dragHandle = panel.querySelector('#zt-drag');
    dragHandle.addEventListener('mousedown', (e) => { isDragging = true; offset = { x: e.clientX - panel.offsetLeft, y: e.clientY - panel.offsetTop }; });
    document.addEventListener('mousemove', (e) => { if (isDragging) { panel.style.left = (e.clientX - offset.x) + 'px'; panel.style.top = (e.clientY - offset.y) + 'px'; panel.style.right = 'auto'; } });
    document.addEventListener('mouseup', () => { isDragging = false; });
})();