Skip to content

Instantly share code, notes, and snippets.

@Ppang0405
Created December 7, 2025 06:11
Show Gist options
  • Select an option

  • Save Ppang0405/f6e13bacf69e98092f2a12976277b55d to your computer and use it in GitHub Desktop.

Select an option

Save Ppang0405/f6e13bacf69e98092f2a12976277b55d to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Grayscale All Images (Auto-Enable)
// @namespace http://tampermonkey.net/
// @version 1.1.0
// @description Automatically grays out all images on page load - toggle with Ctrl+Shift+G or floating button
// @author You
// @match *://*/*
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// Configuration
const STORAGE_KEY = 'grayscale_enabled';
const KEYBOARD_SHORTCUT = 'G'; // Ctrl+Shift+G (or Cmd+Shift+G on Mac)
const AUTO_ENABLE = true; // Set to false to start disabled
// State - defaults to TRUE (auto-enable on every page)
let isGrayscaleEnabled = GM_getValue(STORAGE_KEY, AUTO_ENABLE);
/**
* Inject CSS styles for grayscale effect and toggle button
*/
GM_addStyle(`
/* Grayscale styles */
body.grayscale-mode img,
body.grayscale-mode picture img,
body.grayscale-mode video,
body.grayscale-mode canvas,
body.grayscale-mode svg image {
filter: grayscale(100%) !important;
-webkit-filter: grayscale(100%) !important;
}
/* Floating toggle button */
#grayscale-toggle-btn {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 2147483647;
width: 56px;
height: 56px;
border-radius: 50%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: 3px solid white;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
font-size: 28px;
color: white;
user-select: none;
opacity: 0.9;
}
#grayscale-toggle-btn:hover {
opacity: 1;
transform: scale(1.15);
box-shadow: 0 6px 25px rgba(0, 0, 0, 0.5);
}
#grayscale-toggle-btn.active {
background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);
}
#grayscale-toggle-btn::after {
content: '🎨';
}
#grayscale-toggle-btn.active::after {
content: '⚫';
}
/* Tooltip */
#grayscale-toggle-btn:hover::before {
content: attr(data-tooltip);
position: absolute;
bottom: 65px;
right: 0;
background: rgba(0, 0, 0, 0.95);
color: white;
padding: 10px 14px;
border-radius: 8px;
font-size: 13px;
white-space: nowrap;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
pointer-events: none;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
`);
/**
* Apply grayscale to all images including background images
*/
function applyGrayscale() {
document.body.classList.add('grayscale-mode');
applyGrayscaleToBackgrounds();
isGrayscaleEnabled = true;
GM_setValue(STORAGE_KEY, true);
updateToggleButton();
console.log('βœ… Grayscale mode ENABLED');
}
/**
* Remove grayscale filter from all images
*/
function removeGrayscale() {
document.body.classList.remove('grayscale-mode');
removeGrayscaleFromBackgrounds();
isGrayscaleEnabled = false;
GM_setValue(STORAGE_KEY, false);
updateToggleButton();
console.log('❌ Grayscale mode DISABLED');
}
/**
* Toggle grayscale on/off
*/
function toggleGrayscale() {
if (isGrayscaleEnabled) {
removeGrayscale();
} else {
applyGrayscale();
}
}
/**
* Apply grayscale to elements with background images
*/
function applyGrayscaleToBackgrounds() {
const elements = document.querySelectorAll('*');
elements.forEach(element => {
// Skip the toggle button itself
if (element.id === 'grayscale-toggle-btn') return;
const computedStyle = window.getComputedStyle(element);
const bgImage = computedStyle.backgroundImage;
if (bgImage && bgImage !== 'none' && !element.hasAttribute('data-grayscale-bg')) {
element.setAttribute('data-grayscale-bg', 'true');
const currentFilter = element.style.filter || '';
element.setAttribute('data-original-filter', currentFilter);
element.style.filter = currentFilter ? `${currentFilter} grayscale(100%)` : 'grayscale(100%)';
}
});
}
/**
* Remove grayscale from elements with background images
*/
function removeGrayscaleFromBackgrounds() {
const elements = document.querySelectorAll('[data-grayscale-bg="true"]');
elements.forEach(element => {
const originalFilter = element.getAttribute('data-original-filter');
element.style.filter = originalFilter || '';
element.removeAttribute('data-grayscale-bg');
element.removeAttribute('data-original-filter');
});
}
/**
* Create floating toggle button
*/
function createToggleButton() {
// Remove existing button if any
const existingButton = document.getElementById('grayscale-toggle-btn');
if (existingButton) {
existingButton.remove();
}
const button = document.createElement('div');
button.id = 'grayscale-toggle-btn';
button.setAttribute('data-tooltip', 'Toggle Grayscale (Ctrl+Shift+G)');
button.addEventListener('click', toggleGrayscale);
// Add to page
document.body.appendChild(button);
// Update button state
updateToggleButton();
console.log('πŸ”˜ Toggle button created (bottom-right corner)');
}
/**
* Update toggle button appearance based on state
*/
function updateToggleButton() {
const button = document.getElementById('grayscale-toggle-btn');
if (button) {
if (isGrayscaleEnabled) {
button.classList.add('active');
button.setAttribute('data-tooltip', 'Disable Grayscale (Ctrl+Shift+G)');
} else {
button.classList.remove('active');
button.setAttribute('data-tooltip', 'Enable Grayscale (Ctrl+Shift+G)');
}
}
}
/**
* Check if element has background image and apply grayscale if needed
*/
function checkAndApplyToElement(element) {
if (!isGrayscaleEnabled || !element || element.nodeType !== Node.ELEMENT_NODE) {
return;
}
// Skip the toggle button
if (element.id === 'grayscale-toggle-btn') return;
const computedStyle = window.getComputedStyle(element);
const bgImage = computedStyle.backgroundImage;
if (bgImage && bgImage !== 'none' && !element.hasAttribute('data-grayscale-bg')) {
element.setAttribute('data-grayscale-bg', 'true');
const currentFilter = element.style.filter || '';
element.setAttribute('data-original-filter', currentFilter);
element.style.filter = currentFilter ? `${currentFilter} grayscale(100%)` : 'grayscale(100%)';
}
}
/**
* Observe DOM changes for dynamically loaded images
*/
function initObserver() {
const observer = new MutationObserver((mutations) => {
if (!isGrayscaleEnabled) return;
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
checkAndApplyToElement(node);
if (node.querySelectorAll) {
node.querySelectorAll('*').forEach(checkAndApplyToElement);
}
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
/**
* Setup keyboard shortcut (Ctrl+Shift+G or Cmd+Shift+G)
*/
function setupKeyboardShortcut() {
document.addEventListener('keydown', (event) => {
// Check for Ctrl+Shift+G (Windows/Linux) or Cmd+Shift+G (Mac)
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toUpperCase() === KEYBOARD_SHORTCUT) {
event.preventDefault();
toggleGrayscale();
}
});
}
/**
* Initialize the userscript
*/
function init() {
console.log('🎨 Grayscale userscript loaded (AUTO-ENABLE version)');
// Create toggle button
createToggleButton();
// Setup keyboard shortcut
setupKeyboardShortcut();
// Apply grayscale automatically if enabled
if (isGrayscaleEnabled) {
console.log('⚑ Auto-applying grayscale...');
applyGrayscale();
}
// Observe DOM changes for dynamic content
initObserver();
// Show notification on first run
if (GM_getValue('first_run', true)) {
console.log('πŸ’‘ TIP: This script auto-enables grayscale on all pages!');
console.log('πŸ’‘ Press Ctrl+Shift+G (or Cmd+Shift+G on Mac) to toggle, or use the floating button!');
console.log('πŸ’‘ Look for the button in the bottom-right corner: 🎨 or ⚫');
GM_setValue('first_run', false);
}
}
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment