Wplace Zoom Plus

Adds precision zoom hotkeys (-, +, ])

As of 2025-09-09. See the latest version.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Wplace Zoom Plus
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Adds precision zoom hotkeys (-, +, ])
// @author       Kur0
// @match        https://wplace.live/*
// @grant        unsafeWindow
// @run-at       document-start
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let hooked = false;

    Object.defineProperty(Object.prototype, 'transform', {
        configurable: true,
        enumerable: false,
        set: function(value) {
            // check if it has setZoom and getCanvas
            if (!hooked && value && typeof value.setZoom === 'function' && typeof this.getCanvas === 'function') {
                hooked = true;
                const mapInstance = this;

                console.log('%cWplace Zoom Plus: Map instance captured!', 'color: limegreen; font-weight: bold;');

                // Expose globally for console debugging stuff
                unsafeWindow.myMap = mapInstance;

                console.log("Hotkeys are active: [-] for zoom out, [+] for zoom in, [ ] ] for 1:1 zoom.");

                // Cleanup: remove the hook to prevent side effects
                delete Object.prototype.transform;

                // Set the property on the actual object now that the hook is gone
                this.transform = value;
                return;
            }

            // For all other objects, set the property normally
            Object.defineProperty(this, 'transform', {
                value: value,
                writable: true,
                configurable: true,
                enumerable: true,
            });
        }
    });


    const ONE_TO_ONE_ZOOM = 11.965784285; // log₂(4000)

    document.addEventListener('keydown', (event) => {
        if (!unsafeWindow.myMap) {
            return;
        }

        // Ignore input fields
        const activeElement = document.activeElement;
        if (activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.isContentEditable)) {
            return;
        }

        const getZoom = unsafeWindow.myMap.getZoom.bind(unsafeWindow.myMap);
        const setZoom = unsafeWindow.myMap.setZoom.bind(unsafeWindow.myMap);
        let newZoom;

        const zoomAmount = 0.05;

        switch (event.key) {
            case '-':
                event.preventDefault();
                newZoom = getZoom() - zoomAmount;
                setZoom(newZoom);
                console.log(`Zoom: ${newZoom.toFixed(4)}`);
                break;

            case '+':
            case '=':
                event.preventDefault();
                newZoom = getZoom() + zoomAmount;
                setZoom(newZoom);
                console.log(`Zoom: ${newZoom.toFixed(4)}`);
                break;

            case ']':
                event.preventDefault();
                setZoom(ONE_TO_ONE_ZOOM);
                console.log(`Zoom set to 1:1 pixel level: ${ONE_TO_ONE_ZOOM}`);
                break;

            default:
                break;
        }
    });

})();