非公開 座標自動維持ボタン(離席用)

    @@ -18,7 +18,7 @@ btn.innerHTML = '🌀'; Object.assign(btn.style, { position: 'fixed', - top: '60px', + top: '100px', left: targetLeft + 'px', zIndex: '10000', width: '40px',
  • /*
     * @title 座標自動維持ボタン(離席用)
     * @description 押すとその場でグルグル回り続けるボタンが表示される
     * @private
     */
    javascript:(function(){
        const id = 'afk-rotate-btn';
        if(document.getElementById(id)) return;
    
        /* 1. 位置計算:ゲームコンテナの左端を取得 */
        const container = document.getElementById('game-container');
        const rect = container ? container.getBoundingClientRect() : { left: 0, top: 0 };
        /* 画面端からではなく、コンテナの左端から10pxの位置にする */
        const targetLeft = rect.left + 10;
    
        const btn = document.createElement('button');
        btn.id = id;
        btn.innerHTML = '🌀';
        Object.assign(btn.style, {
            position: 'fixed',
            top: '100px',
            left: targetLeft + 'px',
            zIndex: '10000',
            width: '40px',
            height: '40px',
            lineHeight: '40px',
            textAlign: 'center',
            backgroundColor: 'rgba(0, 0, 0, 0.3)',
            color: '#fff',
            border: '1px solid rgba(255, 255, 255, 0.5)',
            borderRadius: '50%',
            fontSize: '20px',
            cursor: 'pointer',
            padding: '0',
            outline: 'none'
        });
        document.body.appendChild(btn);
    
        /* ウィンドウのリサイズ時に位置を再計算 */
        window.addEventListener('resize', () => {
            const r = container.getBoundingClientRect();
            btn.style.left = (r.left + 10) + 'px';
        });
    
        let rotateInterval = null;
        let step = 0;
        const dirs = [{x: 0, y: -1}, {x: 1, y: 0}, {x: 0, y: 1}, {x: -1, y: 0}];
    
        const stopRotate = () => {
            if (!rotateInterval) return;
            clearInterval(rotateInterval);
            rotateInterval = null;
            btn.style.backgroundColor = 'rgba(0, 0, 0, 0.3)';
            if(typeof inputState !== 'undefined') {
                inputState.dx = 0; inputState.dy = 0; inputState.drawing = false;
                if(typeof sendInput === 'function') sendInput();
            }
        };
    
        btn.onclick = (e) => {
            e.stopPropagation();
            if (rotateInterval) return stopRotate();
            btn.style.backgroundColor = 'rgba(255, 0, 0, 0.6)';
            rotateInterval = setInterval(() => {
                if (typeof inputState !== 'undefined' && typeof sendInput === 'function') {
                    const d = dirs[step++ % 4];
                    inputState.dx = d.x; inputState.dy = d.y; inputState.drawing = true;
                    sendInput();
                }
            }, 200);
        };
    
        ['touchstart', 'mousedown', 'keydown'].forEach(type => {
            window.addEventListener(type, (e) => {
                if (e.target !== btn && rotateInterval) stopRotate();
            }, { capture: true, passive: true });
        });
    })();
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。