Zebra Type Customizer

Animated BG, Text colors, and Font changer.

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ó!)

Advertisement:

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!)

Advertisement:

// ==UserScript==
// @name         Zebra Type Customizer
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Animated BG, Text colors, and Font changer.
// @author       MyUserScripts
// @match        https://zebratype.org/*
// @match        https://zebratype.org/race
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const isCreator = true; 
    const hasUnlocked = true; 

    const bgColors = [
        { val: "linear-gradient(90deg, #00d4ff, #0088cc, #00d4ff)", name: "Cyan" }, 
        { val: "linear-gradient(90deg, #39ff14, #22aa0a, #39ff14)", name: "Lime" }, 
        { val: "linear-gradient(90deg, #ff1493, #aa0e63, #ff1493)", name: "Pink" }, 
        { val: "linear-gradient(90deg, #fdfc47, #b5b432, #fdfc47)", name: "Yellow" }, 
        { val: "linear-gradient(90deg, #ff512f, #aa3620, #ff512f)", name: "Orange" }, 
        { val: "linear-gradient(90deg, #bc13fe, #7e0da9, #bc13fe)", name: "Purple" }, 
        { val: "linear-gradient(90deg, #00ff9f, #00aa6b, #00ff9f)", name: "Mint" }, 
        { val: "linear-gradient(90deg, #ff0000, #aa0000, #ff0000)", name: "Red" },
        { val: "linear-gradient(90deg, #ffffff, #aaaaaa, #ffffff)", name: "White" },
        { val: "linear-gradient(90deg, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c, #bf953f)", name: "Gold", locked: !isCreator, special: true },
        { val: "linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet, red)", name: "Rainbow", locked: !isCreator, special: true }
    ];

    const textColors = [
        { val: "#00d4ff" }, { val: "#39ff14" }, { val: "#ff1493" }, { val: "#fdfc47" }, 
        { val: "#ff512f" }, { val: "#bc13fe" }, { val: "#00ff9f" }, { val: "#ff0000" }
    ];

    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" }
    ];

    const style = document.createElement('style');
    style.innerHTML = `
        @keyframes scrollBG { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } }
        .zt-panel { position: fixed; top: 20px; right: 20px; width: 280px; background: #000; border: 3px solid #fff; border-radius: 15px; padding: 15px; z-index: 10000; color: #fff; font-family: sans-serif; cursor: move; user-select: none; box-shadow: 0 0 20px rgba(255,255,255,0.3); }
        .zt-title { text-align: center; font-weight: bold; margin-bottom: 15px; border-bottom: 1px solid #555; padding-bottom: 5px; }
        .zt-sec { margin-top: 12px; font-weight: bold; font-size: 11px; color: #aaa; text-transform: uppercase; margin-bottom: 5px; }
        .zt-row { display: flex; flex-wrap: wrap; gap: 6px; }
        .zt-btn { width: 28px; height: 28px; border-radius: 50%; border: 1px solid #fff; cursor: pointer; transition: transform 0.3s; position: relative; background-size: 200% 200% !important; animation: scrollBG 2s linear infinite; }
        .zt-btn:hover { transform: scale(1.3); }
        .zt-font-btn { width: auto; padding: 5px 10px; border-radius: 5px; background: #333; color: #fff; border: 1px solid #555; cursor: pointer; font-size: 12px; }
        .zt-font-btn:hover { background: #555; }
        .icon-overlay { position: absolute; top: -8px; left: -8px; font-size: 12px; pointer-events: none; }
        .zt-reset { margin-top: 20px; width: 100%; padding: 10px; cursor: pointer; background: #fff; color: #000; font-weight: bold; border: none; border-radius: 5px; }
    `;
    document.head.appendChild(style);

    const settings = { bgGrad: '#000000', textCol: '#ffffff', font: 'Arial, sans-serif' };

    function updatePage() {
        document.body.style.background = settings.bgGrad;
        document.body.style.backgroundSize = "200% 100%";
        document.body.style.animation = settings.bgGrad.includes('gradient') ? "scrollBG 2s linear infinite" : "none";
        document.body.style.backgroundAttachment = 'fixed';
        
        document.body.style.color = settings.textCol;
        document.body.style.textShadow = !settings.textCol.includes('gradient') ? `0 0 10px ${settings.textCol}` : 'none';
        document.body.style.webkitBackgroundClip = settings.textCol.includes('gradient') ? 'text' : 'unset';
        if(settings.textCol.includes('gradient')) document.body.style.color = 'transparent';
        
        document.body.style.fontFamily = settings.font;
    }

    const panel = document.createElement('div');
    panel.className = 'zt-panel';
    panel.innerHTML = '<div class="zt-title">✨ Neon Zebra Customizer ✨</div>';

    // Background
    const bgSec = document.createElement('div'); bgSec.className = 'zt-sec'; bgSec.innerText = 'Background'; panel.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.special) {
            btn.innerHTML = `<span class="icon-overlay">${(isCreator || hasUnlocked) ? '💎' : '⭐'}</span>`;
            if (!isCreator && !hasUnlocked) btn.innerHTML = `<span class="icon-overlay">🔒</span>`;
        }
        btn.onclick = () => {
            if (item.special && !isCreator && !hasUnlocked) alert("Locked! Unlock to use.");
            else { settings.bgGrad = item.val; updatePage(); }
        };
        bgRow.appendChild(btn);
    });
    panel.appendChild(bgRow);

    // Text
    const txtSec = document.createElement('div'); txtSec.className = 'zt-sec'; txtSec.innerText = 'Text'; panel.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);
    });
    panel.appendChild(txtRow);

    // Font
    const fontSec = document.createElement('div'); fontSec.className = 'zt-sec'; fontSec.innerText = 'Font'; panel.appendChild(fontSec);
    const fontRow = document.createElement('div'); fontRow.className = 'zt-row';
    fonts.forEach(f => {
        const btn = document.createElement('button');
        btn.className = 'zt-font-btn';
        btn.innerText = f.name;
        btn.onclick = () => { settings.font = f.val; updatePage(); };
        fontRow.appendChild(btn);
    });
    panel.appendChild(fontRow);

    const resetBtn = document.createElement('button');
    resetBtn.className = 'zt-reset';
    resetBtn.innerText = 'Reset All';
    resetBtn.onclick = () => { settings.bgGrad = '#000000'; settings.textCol = '#ffffff'; settings.font = 'Arial, sans-serif'; updatePage(); };
    panel.appendChild(resetBtn);
    document.body.appendChild(panel);

    let isDragging = false, offset = { x: 0, y: 0 };
    panel.onmousedown = (e) => { isDragging = true; offset = { x: e.clientX - panel.offsetLeft, y: e.clientY - panel.offsetTop }; };
    document.onmousemove = (e) => { if (isDragging) { panel.style.left = (e.clientX - offset.x) + 'px'; panel.style.top = (e.clientY - offset.y) + 'px'; panel.style.right = 'auto'; } };
    document.onmouseup = () => isDragging = false;
})();