座標自動維持ボタン(離席用)
by
cutfloss
05/03 [2026/05/03 22:36:02]
押すとその場でグルグル回り続けるボタンが表示される
@@ -4,86 +4,61 @@
* @private
*/
javascript:(function(){
- if(document.getElementById('afk-rotate-btn')) return;
+ const id = 'afk-btn';
+ if(document.getElementById(id)) return;
- /* 1. ボタン作成(🌀マークのみの最小サイズ) */
- const btn = document.createElement('button');
- btn.id = 'afk-rotate-btn';
+ /* 1. ゲームコンテナを取得(PCでの位置ずれ防止) */
+ const container = document.getElementById('game-container') || document.body;
+
+ const btn = document.createElement('div');
+ btn.id = id;
btn.innerHTML = '🌀';
Object.assign(btn.style, {
- position: 'fixed',
- top: '60px', /* 左上から少し下げた位置 */
+ position: 'absolute',
+ top: '60px',
left: '10px',
zIndex: '10000',
- width: '40px',
- height: '40px',
- lineHeight: '40px',
+ width: '36px',
+ height: '36px',
+ lineHeight: '36px',
textAlign: 'center',
- backgroundColor: 'rgba(0, 0, 0, 0.3)', /* 控えめな透過黒 */
- color: '#fff',
- border: '1px solid rgba(255, 255, 255, 0.5)',
+ background: 'rgba(0,0,0,0.3)',
borderRadius: '50%',
- fontSize: '20px',
- cursor: 'pointer',
- padding: '0',
- outline: 'none'
+ fontSize: '18px',
+ cursor: 'pointer'
});
- document.body.appendChild(btn);
+ /* コンテナの中に入れることでゲーム画面と一緒に移動させる */
+ container.appendChild(btn);
+
+ let timer = null, step = 0;
+ const dirs = [{x:0,y:-1},{x:1,y:0},{x:0,y:1},{x:-1,y:0}];
- 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)';
- btn.style.borderColor = 'rgba(255, 255, 255, 0.5)';
-
- if(typeof inputState !== 'undefined') {
- inputState.dx = 0;
- inputState.dy = 0;
- inputState.drawing = false;
- if(typeof sendInput === 'function') sendInput();
+ const stop = () => {
+ if (!timer) return;
+ clearInterval(timer);
+ timer = null;
+ btn.style.background = 'rgba(0,0,0,0.3)';
+ if(window.inputState) {
+ inputState.dx = 0; inputState.dy = 0; inputState.drawing = false;
+ if(window.sendInput) sendInput();
}
};
- /* 開始関数 */
- const startRotate = (e) => {
- if (e) e.stopPropagation();
- if (rotateInterval) {
- stopRotate();
- return;
- }
- btn.style.backgroundColor = 'rgba(255, 0, 0, 0.6)'; /* 稼働中は赤く光る */
- btn.style.borderColor = '#fff';
- 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;
+ btn.onclick = (e) => {
+ e.stopPropagation();
+ if (timer) return stop();
+ btn.style.background = 'rgba(255,0,0,0.6)';
+ timer = setInterval(() => {
+ if (window.inputState && window.sendInput) {
+ const d = dirs[step++ % 4];
+ inputState.dx = d.x; inputState.dy = d.y; inputState.drawing = true;
sendInput();
- step++;
}
}, 200);
};
- btn.onclick = startRotate;
-
- /* 2. 操作介入による自動解除のリスナー */
- /* タッチ・マウス・キーボードのいずれかがあったら停止 */
- const inputEvents = ['touchstart', 'mousedown', 'keydown'];
- inputEvents.forEach(eventType => {
- window.addEventListener(eventType, (e) => {
- /* ぐるぐるボタン自体へのクリックは無視して、それ以外の操作で停止 */
- if (e.target !== btn && rotateInterval) {
- stopRotate();
- }
- }, { capture: true, passive: true });
- });
-
- console.log('🌀 Minimal Auto-Rotate: Input-interruption mode active.');
+ /* 操作があったら停止(1つのリスナーで軽量化) */
+ ['mousedown','touchstart','keydown'].forEach(ev =>
+ window.addEventListener(ev, (e) => { if(e.target !== btn) stop(); }, {passive:true})
+ );
})();
/*
* @title 座標自動維持ボタン(離席用)
* @description 押すとその場でグルグル回り続けるボタンが表示される
* @private
*/
javascript:(function(){
const id = 'afk-btn';
if(document.getElementById(id)) return;
/* 1. ゲームコンテナを取得(PCでの位置ずれ防止) */
const container = document.getElementById('game-container') || document.body;
const btn = document.createElement('div');
btn.id = id;
btn.innerHTML = '🌀';
Object.assign(btn.style, {
position: 'absolute',
top: '60px',
left: '10px',
zIndex: '10000',
width: '36px',
height: '36px',
lineHeight: '36px',
textAlign: 'center',
background: 'rgba(0,0,0,0.3)',
borderRadius: '50%',
fontSize: '18px',
cursor: 'pointer'
});
/* コンテナの中に入れることでゲーム画面と一緒に移動させる */
container.appendChild(btn);
let timer = null, step = 0;
const dirs = [{x:0,y:-1},{x:1,y:0},{x:0,y:1},{x:-1,y:0}];
const stop = () => {
if (!timer) return;
clearInterval(timer);
timer = null;
btn.style.background = 'rgba(0,0,0,0.3)';
if(window.inputState) {
inputState.dx = 0; inputState.dy = 0; inputState.drawing = false;
if(window.sendInput) sendInput();
}
};
btn.onclick = (e) => {
e.stopPropagation();
if (timer) return stop();
btn.style.background = 'rgba(255,0,0,0.6)';
timer = setInterval(() => {
if (window.inputState && window.sendInput) {
const d = dirs[step++ % 4];
inputState.dx = d.x; inputState.dy = d.y; inputState.drawing = true;
sendInput();
}
}, 200);
};
/* 操作があったら停止(1つのリスナーで軽量化) */
['mousedown','touchstart','keydown'].forEach(ev =>
window.addEventListener(ev, (e) => { if(e.target !== btn) stop(); }, {passive:true})
);
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。