// ==UserScript== // @name Wplace Symbol Viewer // @namespace Violentmonkey Scripts // @match https://wplace.live/* // @grant none // @version 1.2 // @author Dylan Dang // @description 8/14/2025, 1:57:28 AM // @downloadURL https://update.greasyfork.icu/scripts/545806/Wplace%20Symbol%20Viewer.user.js // @updateURL https://update.greasyfork.icu/scripts/545806/Wplace%20Symbol%20Viewer.meta.js // ==/UserScript== (function () { const SYMBOL_TILES = { Black: 4897444, 'Dark Gray': 4756004, Gray: 15241774, 'Light Gray': 11065002, White: 15269550, 'Deep Red': 33209205, Red: 15728622, Orange: 15658734, Gold: 33226431, Yellow: 33391295, 'Light Yellow': 32641727, 'Dark Green': 15589098, Green: 11516906, 'Light Green': 9760338, 'Dark Teal': 15399560, Teal: 4685802, 'Light Teal': 15587182, Cyan: 29206876, 'Dark Blue': 3570904, Blue: 15259182, Indigo: 29224831, 'Light Indigo': 21427311, 'Dark Purple': 22511061, Purple: 15161013, 'Light Purple': 4667844, 'Dark Pink': 11392452, Pink: 11375466, 'Light Pink': 6812424, 'Dark Brown': 5225454, Brown: 29197179, Beige: 18285009, 'Medium Gray': 31850982, 'Dark Red': 19267878, 'Light Red': 16236308, 'Dark Orange': 33481548, 'Dark Goldenrod': 22708917, Goldenrod: 14352822, 'Light Goldenrod': 7847326, 'Dark Olive': 7652956, Olive: 22501038, 'Light Olive': 28457653, 'Dark Cyan': 9179234, 'Light Cyan': 30349539, 'Light Blue': 4685269, 'Dark Indigo': 18295249, 'Dark Slate Blue': 26843769, 'Slate Blue': 24483191, 'Light Slate Blue': 5211003, 'Dark Peach': 14829567, Peach: 17971345, 'Light Peach': 28873275, 'Light Brown': 4681156, 'Dark Tan': 21392581, Tan: 7460636, 'Light Tan': 23013877, 'Dark Beige': 29010254, 'Light Beige': 18846257, 'Dark Stone': 21825364, Stone: 29017787, 'Light Stone': 4357252, 'Dark Slate': 23057550, Slate: 26880179, 'Light Slate': 5242308, idk: 15237450, }; const SYMBOL_W = 5; const SYMBOL_H = 5; function createSymbolCanvas(symbol, color) { const canvas = document.createElement('canvas'); canvas.width = SYMBOL_W; canvas.height = SYMBOL_H; canvas.style.imageRendering = 'pixelated'; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = color; for (let y = 0; y < SYMBOL_H; y++) { for (let x = 0; x < SYMBOL_W; x++) { const bit_idx = y * SYMBOL_W + x; const bit = (symbol >>> bit_idx) & 1; if (bit) ctx.fillRect(x, y, 1, 1); } } canvas.style.filter = 'drop-shadow(0px 0px 1px black)'; canvas.style.height = '100%'; canvas.style.padding = '5px'; return canvas; } function patchButton(btn) { if (btn.querySelector('canvas')) return; const colorName = btn.ariaLabel; if (!(colorName in SYMBOL_TILES)) return; const symbol = SYMBOL_TILES[colorName]; const color = btn.style.backgroundColor; const canvas = createSymbolCanvas(symbol, color); canvas.dataset.color = color; btn.style.backgroundColor = 'transparent'; btn.appendChild(canvas); } let symbolMode = false; mutationObserver = new MutationObserver(function (mutations) { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeType !== 1) continue; if (node.matches('.absolute.bottom-0.left-0.z-50.w-full')) { const menubar = node.querySelector('.flex.grow.items-center'); const btn = document.createElement('button'); btn.classList.add( 'btn', 'btn-sm', 'btn-circle', 'btn-ghost', 'text-base-content/80', symbolMode ? 'text-primary' : undefined ); btn.innerHTML = ''; menubar.appendChild(btn); const grid = node.querySelector('.grid'); function updateGrid() { if (symbolMode) { for (const button of grid.querySelectorAll('.btn')) { patchButton(button); } } else { for (const canvas of grid.querySelectorAll('canvas')) { const cell = canvas.parentElement; cell.style.backgroundColor = canvas.dataset.color; canvas.remove(); } } } btn.addEventListener('click', () => { if (symbolMode) { btn.classList.remove('text-primary'); } else { btn.classList.add('text-primary'); } symbolMode = !symbolMode; updateGrid(); }); updateGrid(); } if ( symbolMode && node.matches('.tooltip') && node.dataset.tip in SYMBOL_TILES ) { patchButton(node.querySelector('button')); } } } }); mutationObserver.observe(document.body, { childList: true, subtree: true, }); })();