// ==UserScript== // @name 智能自动点击器 (iOS极简版 v1.2) // @namespace http://tampermonkey.net/ // @version 1.2.0 // @description iOS风格UI,支持悬浮球自由拖拽、坐标记忆及自定义快捷键 // @author You // @match *://*/* // @grant none // @run-at document-end // @downloadURL https://update.greasyfork.icu/scripts/558927/%E6%99%BA%E8%83%BD%E8%87%AA%E5%8A%A8%E7%82%B9%E5%87%BB%E5%99%A8%20%28iOS%E6%9E%81%E7%AE%80%E7%89%88%20v12%29.user.js // @updateURL https://update.greasyfork.icu/scripts/558927/%E6%99%BA%E8%83%BD%E8%87%AA%E5%8A%A8%E7%82%B9%E5%87%BB%E5%99%A8%20%28iOS%E6%9E%81%E7%AE%80%E7%89%88%20v12%29.meta.js // ==/UserScript== (function() { 'use strict'; // 注入增强版 iOS 风格 CSS const style = document.createElement('style'); style.innerHTML = ` @supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) { .ios-glass { background: rgba(255, 255, 255, 0.75) !important; -webkit-backdrop-filter: saturate(180%) blur(20px) !important; backdrop-filter: saturate(180%) blur(20px) !important; } } .ios-glass { background: rgba(255, 255, 255, 0.95); border: 1px solid rgba(0, 0, 0, 0.1); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); } .auto-clicker-fab { position: fixed; width: 44px; height: 44px; border-radius: 22px; z-index: 999998; cursor: move; display: flex; align-items: center; justify-content: center; font-size: 20px; transition: transform 0.2s cubic-bezier(0.2, 0, 0.2, 1), box-shadow 0.2s; user-select: none; touch-action: none; } .auto-clicker-fab:active { transform: scale(0.9); } .auto-clicker-panel { position: fixed; z-index: 999997; border-radius: 16px; padding: 20px; display: none; width: 280px; font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif; color: #1d1d1f; } .ios-title { font-size: 17px; font-weight: 600; margin: 0 0 16px 0; text-align: center; } .ios-input-group { margin-bottom: 12px; } .ios-label { display: block; font-size: 12px; font-weight: 500; color: #86868b; margin-bottom: 6px; text-transform: uppercase; } .ios-input { width: 100%; box-sizing: border-box; padding: 10px 12px; background: rgba(0, 0, 0, 0.05); border: none; border-radius: 10px; font-size: 14px; color: #1d1d1f; outline: none; } .ios-shortcut-btn { background: rgba(0, 113, 227, 0.1); color: #0071e3; font-weight: 600; text-align: center; cursor: pointer; padding: 8px; border-radius: 8px; font-size: 13px; } .ios-btn { width: 100%; padding: 12px; border: none; border-radius: 12px; font-size: 15px; font-weight: 600; cursor: pointer; transition: all 0.2s; margin-bottom: 8px; } .ios-btn-primary { background: #0071e3; color: white; } .ios-btn-success { background: #34c759; color: white; } .ios-btn-danger { background: #ff3b30; color: white; } .ios-btn-disabled { background: #e5e5ea; color: #8e8e93; cursor: not-allowed; } .ios-flex-row { display: flex; gap: 8px; } `; document.head.appendChild(style); // 配置初始化 const config = { enabled: false, delay: 1000, clickCount: 0, currentClicks: 0, targetX: 0, targetY: 0, hasTarget: false, shortcut: { ctrl: true, shift: true, key: 'A', display: 'Ctrl + Shift + A' }, fabPos: { top: '20px', left: 'auto', right: '20px' } }; // 加载本地配置 const savedConfig = localStorage.getItem('auto_clicker_v12_config'); if (savedConfig) Object.assign(config, JSON.parse(savedConfig)); // 创建元素 const cursor = document.createElement('div'); cursor.style.cssText = `position: fixed; width: 30px; height: 30px; border: 2px solid #0071e3; border-radius: 50%; pointer-events: none; z-index: 999999; display: none; background: rgba(0, 113, 227, 0.1); transform: translate(-50%, -50%); transition: transform 0.1s;`; const mainButton = document.createElement('div'); mainButton.className = 'auto-clicker-fab ios-glass'; mainButton.innerHTML = '⚙️'; Object.assign(mainButton.style, config.fabPos); const panel = document.createElement('div'); panel.className = 'auto-clicker-panel ios-glass'; // 面板跟随悬浮球位置逻辑 const updatePanelPos = () => { const rect = mainButton.getBoundingClientRect(); panel.style.top = (rect.bottom + 10) + 'px'; panel.style.left = (rect.right - 280) + 'px'; }; panel.innerHTML = `

点击器设置

${config.shortcut.display}
`; document.body.append(cursor, mainButton, panel); // 拖拽逻辑 let isDragging = false, dragX, dragY; mainButton.addEventListener('mousedown', (e) => { isDragging = true; dragX = e.clientX - mainButton.offsetLeft; dragY = e.clientY - mainButton.offsetTop; mainButton.style.transition = 'none'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; let x = e.clientX - dragX, y = e.clientY - dragY; mainButton.style.left = x + 'px'; mainButton.style.top = y + 'px'; mainButton.style.right = 'auto'; if (panel.style.display === 'block') updatePanelPos(); }); document.addEventListener('mouseup', () => { if (!isDragging) return; isDragging = false; mainButton.style.transition = 'transform 0.2s'; config.fabPos = { top: mainButton.style.top, left: mainButton.style.left, right: 'auto' }; saveConfig(); }); // 快捷键录制 let isRecording = false; const shortcutBtn = document.getElementById('shortcut-display'); shortcutBtn.addEventListener('click', () => { isRecording = true; shortcutBtn.innerText = '请按下按键...'; shortcutBtn.style.background = '#ff9500'; shortcutBtn.style.color = 'white'; }); document.addEventListener('keydown', (e) => { if (isRecording) { e.preventDefault(); const keys = []; if (e.ctrlKey) keys.push('Ctrl'); if (e.shiftKey) keys.push('Shift'); if (e.altKey) keys.push('Alt'); if (!['Control', 'Shift', 'Alt'].includes(e.key)) keys.push(e.key.toUpperCase()); config.shortcut = { ctrl: e.ctrlKey, shift: e.shiftKey, alt: e.altKey, key: e.key.toUpperCase(), display: keys.join(' + ') }; shortcutBtn.innerText = config.shortcut.display; shortcutBtn.style = ''; isRecording = false; saveConfig(); return; } // 匹配快捷键启动/停止 const s = config.shortcut; if (e.ctrlKey === s.ctrl && e.shiftKey === s.shift && e.altKey === s.alt && e.key.toUpperCase() === s.key) { e.preventDefault(); config.enabled ? stopClicking() : startClicking(); } }); // 核心功能逻辑 function saveConfig() { localStorage.setItem('auto_clicker_v12_config', JSON.stringify(config)); } mainButton.addEventListener('click', () => { const isVisible = panel.style.display === 'block'; panel.style.display = isVisible ? 'none' : 'block'; if (!isVisible) updatePanelPos(); }); const setPosBtn = document.getElementById('set-position-btn'); const startBtn = document.getElementById('start-btn'); const stopBtn = document.getElementById('stop-btn'); let clickInterval = null; setPosBtn.addEventListener('click', () => { setPosBtn.innerText = '请点击目标...'; setPosBtn.style.background = '#ff9500'; cursor.style.display = 'block'; const handler = (e) => { e.preventDefault(); e.stopPropagation(); config.targetX = e.clientX; config.targetY = e.clientY; config.hasTarget = true; saveConfig(); document.removeEventListener('click', handler, true); cursor.style.display = 'none'; setPosBtn.innerText = '📍 重新设置位置'; setPosBtn.style.background = ''; }; document.addEventListener('click', handler, true); }); function performClick() { if (config.clickCount > 0 && config.currentClicks >= config.clickCount) return stopClicking(); const el = document.elementFromPoint(config.targetX, config.targetY); if (el) { const init = { view: window, bubbles: true, cancelable: true, clientX: config.targetX, clientY: config.targetY, button: 0 }; ['mousedown', 'mouseup', 'click'].forEach(t => el.dispatchEvent(new MouseEvent(t, init))); } config.currentClicks++; document.getElementById('click-counter') && (document.getElementById('click-counter').innerText = config.currentClicks); } function startClicking() { if (!config.hasTarget) return alert('请先设置位置'); config.enabled = true; config.currentClicks = 0; startBtn.disabled = true; startBtn.className = 'ios-btn ios-btn-disabled'; stopBtn.disabled = false; stopBtn.className = 'ios-btn ios-btn-danger'; mainButton.innerHTML = '🔴'; clickInterval = setInterval(performClick, config.delay); } function stopClicking() { config.enabled = false; clearInterval(clickInterval); startBtn.disabled = false; startBtn.className = 'ios-btn ios-btn-primary'; stopBtn.disabled = true; stopBtn.className = 'ios-btn ios-btn-disabled'; mainButton.innerHTML = '⚙️'; } startBtn.addEventListener('click', startClicking); stopBtn.addEventListener('click', stopClicking); document.getElementById('click-delay').addEventListener('change', (e) => { config.delay = e.target.value; saveConfig(); }); document.getElementById('click-count').addEventListener('change', (e) => { config.clickCount = e.target.value; saveConfig(); }); })();