您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
🍳 and 🔍. Space + drag to pan, Z to zoom, and shift + Z to reset
// ==UserScript== // @name 🍳 Zoom // @namespace https://greasyfork.org/users/281093 // @match https://sketchful.io/ // @grant none // @version 1.2 // @author Bell // @description 🍳 and 🔍. Space + drag to pan, Z to zoom, and shift + Z to reset // @run-at body-end // ==/UserScript== // Options const options = { onlyFreedraw: true, resetOnZoomOut: true } ////// const canvas = document.querySelector('#canvas'); const zoomContainer = document.createElement('div'); const sheet = window.document.styleSheets[window.document.styleSheets.length - 1]; const resetObserver = new MutationObserver(resetCanvas); const panContainer = document.createElement('div'); let panning = false; const startPos = {}; let canvasOffset = {}; let zoomed = false; (function init() { panContainer.style.position = 'relative'; panContainer.style.transition = 'transform 0.1s ease'; zoomContainer.style.overflow = 'hidden'; zoomContainer.id = 'zoomContainer'; sheet.insertRule('.dark #zoomContainer { background: #2C2F33}'); sheet.insertRule('#zoomContainer { background: #c8c8c8}'); wrap(canvas, zoomContainer); wrap(canvas, panContainer); resetCanvas(); resetObserver.observe(document.querySelector('#gameSticky'), { childList: true, }); document.addEventListener('keydown', keyDown, false); document.addEventListener('keyup', stopPanning, false); zoomContainer.addEventListener('pointerdown', getStartPos, true); zoomContainer.addEventListener('pointermove', moveCanvas, true); document.addEventListener('pointerup', stopMoving, false); })(); function wrap(toWrap, wrapper) { toWrap.parentNode.appendChild(wrapper); wrapper.appendChild(toWrap); } function regenerateCursor() { const selectedTool = document.querySelector('.gameToolsSelected'); selectedTool.id === 'gameToolsDraw' ? selectedTool.nextSibling.click() : selectedTool.previousSibling.click(); selectedTool.click(); } function stopPanning(e) { if (e.code !== 'Space' || !panning) return; e.preventDefault(); regenerateCursor(); zoomContainer.style.cursor = 'default'; panning = false; } function keyDown(e) { if (!isDrawing() || !isFreeDraw() && options.onlyFreedraw) return; switch (e.code) { case 'Space': if (e.shiftKey) return; startPanning(); e.preventDefault(); break; case 'KeyZ': if (e.ctrlKey) { return; } else if (e.shiftKey && !options.resetOnZoomOut) { resetCanvas(); e.stopImmediatePropagation(); return; } toggleZoom(); e.stopImmediatePropagation(); } } function toggleZoom() { panContainer.style.transform = zoomed ? '' : 'scale(2)'; if (zoomed && options.resetOnZoomOut) resetCanvas(); else zoomed = !zoomed; } function startPanning() { if (panning || !zoomed && options.resetOnZoomOut) return; canvas.style.cursor = 'grab'; zoomContainer.style.cursor = 'grab'; panning = true; } function moveCanvas(e) { if (!panning || !e.buttons) return; const offset = {}; offset.x = e.clientX - startPos.x; offset.y = e.clientY - startPos.y; panContainer.style.left = `${canvasOffset.x + offset.x}px`; panContainer.style.top = `${canvasOffset.y + offset.y}px`; e.preventDefault(); e.stopImmediatePropagation(); } function getStartPos(e) { if (!panning) return; startPos.x = e.clientX; startPos.y = e.clientY; canvas.style.cursor = 'grabbing'; zoomContainer.style.cursor = 'grabbing'; e.preventDefault(); e.stopImmediatePropagation(); } function stopMoving(e) { canvasOffset.x = parseInt(panContainer.style.left.match(/-?\d+/)[0]); canvasOffset.y = parseInt(panContainer.style.top.match(/-?\d+/)[0]); if (panning) { canvas.style.cursor = 'grab'; zoomContainer.style.cursor = 'grab'; e.stopImmediatePropagation(); } } function resetCanvas() { panContainer.style.left = '0px'; panContainer.style.top = '0px'; panContainer.style.transform = ''; zoomed = false; canvasOffset = { x: 0, y: 0 }; } function isDrawing() { return ( document.querySelector('#gameTools').style.display !== 'none' && document.querySelector('body > div.game').style.display !== 'none' && document.activeElement !== document.querySelector('#gameChatInput') ); } function isFreeDraw() { return ( canvas.style.display !== 'none' && document.querySelector('#gameClock').style.display === 'none' && document.querySelector('#gameSettings').style.display === 'none' ); }