Poxel Crosshair

Custom Crosshairs for poxel.io

// ==UserScript==
// @name         Poxel Crosshair
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Custom Crosshairs for poxel.io
// @author       ceborix
// @match        *://*poxel.io/*
// @match         *://*kour.io/* 
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const STORAGE_KEY = 'crosshair-settings';
    function saveSettings(style) {
        localStorage.setItem(STORAGE_KEY, JSON.stringify({ style }));
    }
    function loadSettings() {
        return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
    }

    const state = {
        currentStyle: 'ceborix',
        ...loadSettings()
    };

    const crosshair = document.createElement('div');
    crosshair.id = 'custom-crosshair';
    crosshair.style.position = 'fixed';
    crosshair.style.top = '50%';
    crosshair.style.left = '50%';
    crosshair.style.transform = 'translate(-50%, -50%)';
    crosshair.style.zIndex = '9999';
    crosshair.style.pointerEvents = 'none';
    document.body.appendChild(crosshair);

    function clearCrosshair() {
        crosshair.innerHTML = '';
        crosshair.style.background = '';
        crosshair.style.border = '';
        crosshair.style.borderRadius = '';
        crosshair.style.filter = '';
        crosshair.style.width = '';
        crosshair.style.height = '';
        crosshair.style.maskImage = '';
        crosshair.style.webkitMaskImage = '';
        crosshair.style.display = 'none';
    }

    function applyCrosshair(style) {
        clearCrosshair();
        if (!style) return;

        crosshair.style.display = 'flex';
        crosshair.style.alignItems = 'center';
        crosshair.style.justifyContent = 'center';

        switch (style) {
            case 'myrrr':
                crosshair.style.width = '15px';
                crosshair.style.height = '15px';
                crosshair.style.filter = 'drop-shadow(0 0 5px #fff) drop-shadow(0 0 10px #ccf) drop-shadow(0 0 15px #ddf)';
                const horiz = document.createElement('div');
                Object.assign(horiz.style, {
                    position: 'absolute',
                    width: '15px',
                    height: '4px',
                    background: 'linear-gradient(to bottom, #ffffff, #e0ccff)',
                    borderRadius: '1px',
                });
                const vert = document.createElement('div');
                Object.assign(vert.style, {
                    position: 'absolute',
                    width: '4px',
                    height: '15px',
                    background: 'linear-gradient(to bottom, #ffffff, #e0ccff)',
                    borderRadius: '1px',
                });
                crosshair.appendChild(horiz);
                crosshair.appendChild(vert);
                break;

            case 'dot':
                crosshair.style.width = '8px';
                crosshair.style.height = '8px';
                crosshair.style.borderRadius = '50%';
                crosshair.style.background = '#fff';
                crosshair.style.filter = 'drop-shadow(0 0 4px #66f)';
                break;

            case 'shotgun':
                crosshair.style.width = '20px';
                crosshair.style.height = '20px';
                crosshair.style.border = '2px solid #0ff';
                crosshair.style.borderRadius = '50%';
                crosshair.style.boxSizing = 'border-box';
                crosshair.style.background = 'rgba(255, 255, 255, 0.1)';
                crosshair.style.filter = 'drop-shadow(0 0 6px #0ff)';
                break;

            case 'ceborix':
                crosshair.style.width = '12px';
                crosshair.style.height = '12px';
                crosshair.style.filter = '';
                const horizCeborix = document.createElement('div');
                Object.assign(horizCeborix.style, {
                    position: 'absolute',
                    width: '12px',
                    height: '4px',
                    background: '#fff',
                    borderRadius: '1px',
                });
                const vertCeborix = document.createElement('div');
                Object.assign(vertCeborix.style, {
                    position: 'absolute',
                    width: '4px',
                    height: '12px',
                    background: '#fff',
                    borderRadius: '1px',
                });
                crosshair.appendChild(horizCeborix);
                crosshair.appendChild(vertCeborix);
                break;
        }
    }

    const style = document.createElement('style');
    style.textContent = `
        #crosshair-settings {
            position: fixed;
            top: 150px;
            right: 10px;
            z-index: 99999;
            font-family: Arial, sans-serif;
            background-color: #222;
            border-radius: 10px;
            padding: 15px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
            transition: opacity 0.3s ease, transform 0.3s ease;
        }

        #crosshair-settings-button {
            background: transparent;
            border: none;
            font-size: 24px;
            color: #fff;
            cursor: pointer;
            filter: drop-shadow(0 0 3px #000);
            transition: transform 0.3s ease;
        }

        #crosshair-settings-button:hover {
            transform: scale(1.1);
        }

        #crosshair-menu {
            display: none;
            flex-direction: column;
            margin-top: 10px;
            background: rgba(30, 30, 30, 0.95);
            border-radius: 10px;
            padding: 10px;
            box-shadow: 0 0 10px #000;
            transition: opacity 0.3s ease-in-out;
        }

        .crosshair-option {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 8px 0;
            color: #fff;
            font-size: 14px;
        }

        .switch {
            position: relative;
            display: inline-block;
            width: 40px;
            height: 20px;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 20px;
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 16px;
            width: 16px;
            left: 2px;
            bottom: 2px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }

        input:checked + .slider {
            background-color: #4caf50;
        }

        input:checked + .slider:before {
            transform: translateX(20px);
        }
    `;
    document.head.appendChild(style);

    const menuContainer = document.createElement('div');
    menuContainer.id = 'crosshair-settings';

    const settingsButton = document.createElement('button');
    settingsButton.id = 'crosshair-settings-button';
    settingsButton.innerHTML = '⚙️';

    const menu = document.createElement('div');
    menu.id = 'crosshair-menu';

const crosshairOptions = [
    { label: "ceborix's crosshair", key: 'ceborix' },
    { label: "myrrr's crosshair", key: 'myrrr' },
    { label: 'Dot', key: 'dot' },
    { label: 'Shotgun', key: 'shotgun' }
];

    function createOption(label, styleKey) {
        const row = document.createElement('div');
        row.className = 'crosshair-option';

        const text = document.createElement('span');
        text.textContent = label;

        const toggleContainer = document.createElement('label');
        toggleContainer.className = 'switch';

        const toggle = document.createElement('input');
        toggle.type = 'checkbox';
        toggle.checked = state.currentStyle === styleKey;

        const slider = document.createElement('span');
        slider.className = 'slider';

        toggle.onchange = () => {
            if (toggle.checked) {
                state.currentStyle = styleKey;
                saveSettings(state.currentStyle);
                applyCrosshair(state.currentStyle);

                document.querySelectorAll('#crosshair-menu input[type=checkbox]').forEach(cb => {
                    if (cb !== toggle) cb.checked = false;
                });
            } else {
                state.currentStyle = null;
                saveSettings(null);
                clearCrosshair();
            }
        };

        toggleContainer.appendChild(toggle);
        toggleContainer.appendChild(slider);
        row.appendChild(text);
        row.appendChild(toggleContainer);
        return row;
    }

    crosshairOptions.forEach(opt => menu.appendChild(createOption(opt.label, opt.key)));

    menuContainer.onclick = (e) => {
    if (e.target.closest('#crosshair-menu')) return;

        menu.style.display = menu.style.display === 'flex' ? 'none' : 'flex';
    };


    menuContainer.appendChild(settingsButton);
    menuContainer.appendChild(menu);
    document.body.appendChild(menuContainer);

    applyCrosshair(state.currentStyle);
})();
//special thanks to myrrr who fixed some bugs with me