// ==UserScript== // @name (Global) Image Zoomer // @description Allows zooming into images without changing pages. Hold Ctrl+Shift (Cmd+Shift on MAC) when clicking on an image to load it with the script. // @version 2022.12.17.17.31 // @author MetalTxus // @namespace https://github.com/jesuscc1993 // @match *://*/* // @exclude *youtube.com/embed* // @icon https://dl.dropbox.com/s/4mnevtuyvt1eden/48.png // @require http://code.jquery.com/jquery-3.2.1.min.js // @require https://raw.githubusercontent.com/jesuscc1993/user-js/master/libraries/key-navigation.js // ==/UserScript== /* globals jQuery */ const ENABLED_FOR_LINKS = true; const preloader = 'https://dl.dropbox.com/s/xbxkvw77dfsrum4/preloader.svg'; const extensions = ['.jpg', '.jpeg', '.png', '.gif']; const setUpKeyNavigation = window.setUpKeyNavigation; const gizContainer = jQuery(`
`); const gizAnchor = jQuery(``); const gizImage = jQuery(``); const gizPreloader = jQuery(``); const gizClose = jQuery(``); const initialize = () => { jQuery(` `).appendTo('head'); gizContainer.click(hideContainer); gizClose.click(hideContainer); gizAnchor.append(gizImage); gizContainer.append(gizAnchor); gizContainer.append(gizPreloader); gizContainer.append(gizClose); jQuery('body').append(gizContainer); gizImage .on('load', event => { const newUrl = event.target.src; gizAnchor.attr('href', newUrl); showImage(); }) .on('error', () => { const url = gizImage.attr('src'); for (var i = 0; i < extensions.length; i++) { if (url.includes(extensions[i])) { const newUrl = url.replace(extensions[i], extensions[i + 1]); gizImage.attr('src', newUrl); break; } } }); jQuery(document).click(event => { if ( (event.ctrlKey || event.metaKey) && event.shiftKey && event.target.nodeName.toLowerCase() === 'img' && (ENABLED_FOR_LINKS || event.parentElement.target.nodeName !== 'A') ) { event.preventDefault(); loadPreview(event.target); } }); jQuery(window).resize(() => { if (gizContainer.is(':visible')) { relocateImage(); } }); setUpKeyNavigation({ onLeftPressed: e => isContainerVisible() && loadSiblingImage(-1) && e.preventDefault(), onRightPressed: e => isContainerVisible() && loadSiblingImage(1) && e.preventDefault(), onDownPressed: e => isContainerVisible() && hideContainer() && e.preventDefault(), onUpPressed: e => isContainerVisible() && e.preventDefault(), }); console.info(`Script "Global Image Zoomer" ready for use on ${location.origin}`); }; const loadPreview = element => { let newURL = element.src; if (newURL !== undefined && element.nodeName === 'IMG') { newURL = parseURL(newURL); if (removeExtension(newURL) !== removeExtension(gizImage.attr('src')) && newURL !== preloader) { loadImageUrl(newURL); } showContainer(); } }; const loadImageUrl = newURL => { showPreloader(); gizImage.attr('src', newURL); gizAnchor.attr('href', newURL); }; const loadSiblingImage = increment => { if (!isContainerVisible()) return; const imagesUrls = [ ...new Set( jQuery('img:not(#giz-preloader)') .map((i, img) => img.src) .toArray() ) ]; const currentImageUrl = gizImage.attr('src'); const currentIndex = imagesUrls.indexOf(currentImageUrl); let requestedIndex = currentIndex + increment; if (requestedIndex < 0 || requestedIndex >= imagesUrls.length) { requestedIndex = currentIndex; hideContainer(); } /*const newIndex = requestedIndex < 0 ? 0 : requestedIndex >= imagesUrls.length ? imagesUrls.length - 1 : requestedIndex;*/ const newIndex = requestedIndex; loadImageUrl(imagesUrls[newIndex]); }; const parseURL = url => { if (urlContains('deviantart.com')) { url = url.replace('/200H/', '/').replace('/150/', '/'); } else if (urlContains('zerochan.net')) { url = url.replace('s3.', 'static.').replace('.240.', '.full.'); } return url; }; const urlContains = text => { return window.location.href.includes(text); }; const removeExtension = url => { if (url) { extensions.forEach(extension => { url = url.replace(extension, ''); }); } return url; }; const relocateImage = () => { return gizImage.css('margin', `${-Math.ceil(gizImage.height() / 2)}px ${-Math.ceil(gizImage.width() / 2)}px`); }; const hideContainer = () => { return gizContainer.fadeOut(100); }; const showContainer = () => { return gizContainer.fadeIn(100); }; const isContainerVisible = () => { return !jQuery('#giz-container').is(':hidden'); } const hidePreloader = () => { return gizPreloader.hide(); }; const showPreloader = () => { return hideImage() && gizPreloader.show(); }; const hideImage = () => { return gizImage.hide(); }; const showImage = () => { return relocateImage() && hidePreloader() && gizImage.show(); }; setTimeout(() => { if (!jQuery('#giz-container').length) { initialize(); } });