Zoom on Hover enlarges images when you hover over them.
当前为
// ==UserScript==
// @name Zoom on Hover
// @name:es Zoom on Hover
// @version 1.6.2
// @description Zoom on Hover enlarges images when you hover over them.
// @description:es Zoom on Hover amplía las imágenes cuando pasas el cursor sobre ellas.
// @author Adam Jensen
// @match *://*/*
// @grant GM_addStyle
// @license MIT
// @namespace https://greasyfork.org/users/1398884
// ==/UserScript==
(function() {
'use strict';
// Configuration
const MAX_WIDTH = 500; // Maximum width of the enlarged image
const MAX_HEIGHT = 500; // Maximum height of the enlarged image
const ZOOM_FACTOR = 2; // Zoom factor (1x, 1.5x, 2x, 3x, etc)
const MAX_SIZE = 800; // Maximum size in pixels (If an image has width or height greater than or equal to MAX_SIZE, it won't be enlarged)
const MIN_SIZE = 50; // Minimum size in pixels (Images smaller than this size won't be enlarged)
const MAX_DISPLAY_TIME = 2; // Maximum duration (in seconds) for how long the enlarged image stays visible
// Styles
GM_addStyle(`
.ampliar-img-flotante {
position: absolute;
z-index: 9999;
border: 2px solid #ccc;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
display: none;
padding: 0px;
pointer-events: none;
height: auto;
width: auto;
box-sizing: border-box;
}
.ampliar-img-flotante img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
margin: 0;
box-sizing: border-box;
}
`);
// Create the floating window
const ventanaFlotante = document.createElement('div');
ventanaFlotante.classList.add('ampliar-img-flotante');
const imagenFlotante = document.createElement('img');
ventanaFlotante.appendChild(imagenFlotante);
document.body.appendChild(ventanaFlotante);
let timer; // To store the timeout for hiding the floating window
// Function to enlarge the image with the zoom factor
const ampliarImagen = (event) => {
const target = event.target;
let imgSrc = '';
if (target.tagName === 'IMG') {
// If the element is an <img>, use the src attribute
imgSrc = target.src;
// Skip images with "logo" or "icon" in the alt attribute
const altText = target.alt ? target.alt.toLowerCase() : '';
if (altText.includes('logo') || altText.includes('icon')) {
return;
}
} else if (target.style.backgroundImage) {
// If the element has a background image, extract the URL
imgSrc = target.style.backgroundImage.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
}
// Skip images from unwanted sources
if (!imgSrc || imgSrc.includes('youtube.com') || imgSrc.includes('gstatic.com')) {
return;
}
// If the current image is the same as the previous one, return
if (imagenFlotante.src === imgSrc) {
return;
}
// Hide the floating window if an image is already displayed
if (ventanaFlotante.style.display === 'block') {
ocultarVentanaFlotante(); // Hide and reset
}
const img = new Image();
img.onload = () => {
// Don't enlarge images that are already large enough
if (img.width >= MAX_SIZE || img.height >= MAX_SIZE) {
return;
}
// Don't enlarge images that are too small
if (img.width < MIN_SIZE || img.height < MIN_SIZE) {
return;
}
const widthWithZoom = img.width * ZOOM_FACTOR;
const heightWithZoom = img.height * ZOOM_FACTOR;
let finalWidth, finalHeight;
if (img.width > img.height) {
finalWidth = Math.min(widthWithZoom, MAX_WIDTH);
finalHeight = (img.height * finalWidth) / img.width;
if (finalHeight > MAX_HEIGHT) {
finalHeight = MAX_HEIGHT;
finalWidth = (img.width * finalHeight) / img.height;
}
} else {
finalHeight = Math.min(heightWithZoom, MAX_HEIGHT);
finalWidth = (img.width * finalHeight) / img.height;
if (finalWidth > MAX_WIDTH) {
finalWidth = MAX_WIDTH;
finalHeight = (img.height * finalWidth) / img.width;
}
}
imagenFlotante.src = imgSrc;
ventanaFlotante.style.display = 'block';
ventanaFlotante.style.width = `${finalWidth}px`;
ventanaFlotante.style.height = `${finalHeight}px`;
// Calculate the position of the floating window
const { top, left, width, height } = target.getBoundingClientRect();
let newTop = top + window.scrollY;
let newLeft = left + width + window.scrollX;
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
// Adjust the position to avoid overflow to the right
if (newLeft + ventanaFlotante.offsetWidth > viewportWidth) {
newLeft = left - ventanaFlotante.offsetWidth + window.scrollX;
}
// Adjust the position to avoid overflow to the bottom
if (newTop + ventanaFlotante.offsetHeight > viewportHeight + window.scrollY) {
newTop = top + height + window.scrollY - ventanaFlotante.offsetHeight;
}
// Adjust the position to avoid overflow to the top
if (newTop < window.scrollY) {
newTop = window.scrollY;
}
ventanaFlotante.style.top = `${newTop}px`;
ventanaFlotante.style.left = `${newLeft}px`;
// Set a timer to automatically hide the floating window after MAX_DISPLAY_TIME
clearTimeout(timer); // Clear any previous timer
timer = setTimeout(ocultarVentanaFlotante, MAX_DISPLAY_TIME * 1000); // Hide after MAX_DISPLAY_TIME seconds
};
img.src = imgSrc;
};
// Hide the floating window and reset the image source
const ocultarVentanaFlotante = () => {
ventanaFlotante.style.display = 'none';
imagenFlotante.src = ''; // Reset the image source
};
// Detect images
const detectarImagenes = () => {
const elements = document.querySelectorAll('img, [style*="background-image"]');
elements.forEach((target) => {
if (target.tagName === 'IMG') {
target.addEventListener('mouseenter', ampliarImagen);
target.addEventListener('mouseleave', ocultarVentanaFlotante);
} else if (target.style.backgroundImage) {
target.addEventListener('mouseenter', ampliarImagen);
target.addEventListener('mouseleave', ocultarVentanaFlotante);
}
});
};
// Call the function to detect images
detectarImagenes();
// Add a mutation observer to detect dynamically added images or background elements
const observer = new MutationObserver(detectarImagenes);
observer.observe(document.body, { childList: true, subtree: true });
})();