Created
January 26, 2026 19:10
-
-
Save mhdcodes/dfee1074815ca68c9206c5a4c669a30e to your computer and use it in GitHub Desktop.
Photopea No Ads
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Photopea No Ads | |
| // @version 1.0.0 | |
| // @description Remove ads sidebar and maximize canvas workspace in Photopea by spoofing viewport width | |
| // @icon https://www.photopea.com/promo/icon512.png | |
| // @author Claude (based on ml98's approach) | |
| // @namespace http://tampermonkey.net/ | |
| // @license MIT | |
| // @match https://www.photopea.com/* | |
| // @match https://vecpea.com/* | |
| // @grant unsafeWindow | |
| // @run-at document-idle | |
| // ==/UserScript== | |
| (function () { | |
| "use strict"; | |
| String.prototype.split=(f=>function(){return f.apply(this.replace('photopea','vectorpea'),arguments)})(String.prototype.split); | |
| function maximizeWorkspace() { | |
| // Find the app container and its child | |
| const appContainer = document.querySelector(".app"); | |
| const appChild = document.querySelector(".app > div"); | |
| if (!appContainer || !appChild) { | |
| console.log("Photopea containers not found yet, retrying..."); | |
| return false; | |
| } | |
| // Calculate the width of the ad sidebar | |
| const adWidth = appContainer.offsetWidth - appChild.offsetWidth; | |
| console.log("Ad sidebar width detected:", adWidth); | |
| // Override window.innerWidth to include the ad width | |
| // This tricks Photopea into thinking the viewport is wider | |
| // causing it to push ads off-screen | |
| Object.defineProperty(unsafeWindow, "innerWidth", { | |
| get() { | |
| return parseInt(visualViewport.width) + adWidth; | |
| }, | |
| configurable: true, | |
| }); | |
| // Trigger a resize event so Photopea recalculates its layout | |
| unsafeWindow.dispatchEvent(new Event("resize")); | |
| console.log("Photopea workspace maximized!"); | |
| return true; | |
| } | |
| // Use MutationObserver to detect when Photopea's app container loads | |
| const observer = new MutationObserver((mutations) => { | |
| for (const mutation of mutations) { | |
| for (const node of mutation.addedNodes) { | |
| // Check if the added node is part of Photopea's app structure | |
| if (node.nodeType === 1 && node.matches(".app *")) { | |
| console.log("Photopea app detected, maximizing workspace..."); | |
| // Disconnect observer once we've found the app | |
| observer.disconnect(); | |
| // Small delay to ensure DOM is fully rendered | |
| setTimeout(() => { | |
| if (maximizeWorkspace()) { | |
| // Success - workspace maximized | |
| } else { | |
| // Fallback: try again after a longer delay | |
| setTimeout(maximizeWorkspace, 500); | |
| } | |
| }, 100); | |
| return; | |
| } | |
| } | |
| } | |
| }); | |
| // Start observing the document body for changes | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true, | |
| }); | |
| // Fallback: If app is already loaded, maximize immediately | |
| setTimeout(() => { | |
| const appExists = document.querySelector(".app > div"); | |
| if (appExists) { | |
| console.log("Photopea already loaded, maximizing workspace..."); | |
| observer.disconnect(); | |
| maximizeWorkspace(); | |
| } | |
| }, 1000); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment