Zoom on Hover

Zoom on Hover enlarges images when you hover over them.

目前為 2024-11-25 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Zoom on Hover
// @name:es      Zoom on Hover
// @version      1.0
// @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';

    // Estilos
    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;
            overflow: hidden;
            padding: 5px;
            pointer-events: none;
            /* Eliminada la transición para evitar el "parpadeo" */
        }
        .ampliar-img-flotante img {
            width: 100%;
            height: 100%;
            object-fit: contain; /* Mantener la relación de aspecto sin recorte */
        }
    `);

    // Crear la ventana flotante
    const ventanaFlotante = document.createElement('div');
    ventanaFlotante.classList.add('ampliar-img-flotante');
    const imagenFlotante = document.createElement('img');
    ventanaFlotante.appendChild(imagenFlotante);
    document.body.appendChild(ventanaFlotante);

    // Función para ampliar la imagen
    const ampliarImagen = (event) => {
        const img = event.target;

        if (img.tagName !== 'IMG' || img.width < 50 || img.height < 50 || img.src.includes('youtube.com') || img.src.includes('gstatic.com')) {
            return; // No ampliar si es un logo de YouTube o una imagen pequeña
        }

        // Crear una nueva imagen para cargarla
        const imagenPrevia = new Image();
        imagenPrevia.src = img.src;

        // Esperamos a que la imagen se cargue
        imagenPrevia.onload = () => {
            // Ajustar el tamaño del contenedor flotante según las dimensiones de la imagen
            const imageAspectRatio = imagenPrevia.width / imagenPrevia.height;
            const containerAspectRatio = ventanaFlotante.offsetWidth / ventanaFlotante.offsetHeight;

            if (imageAspectRatio > containerAspectRatio) {
                // Si la imagen es más ancha que el contenedor, ajustamos el ancho
                ventanaFlotante.style.width = `${Math.min(imagenPrevia.width, 600)}px`;
                ventanaFlotante.style.height = 'auto';
            } else {
                // Si la imagen es más alta que ancha, ajustamos la altura
                ventanaFlotante.style.height = `${Math.min(imagenPrevia.height, 600)}px`;
                ventanaFlotante.style.width = 'auto';
            }

            // Asignar la imagen al contenedor flotante y mostrarla
            imagenFlotante.src = img.src;
            ventanaFlotante.style.display = 'block';

            // Calcular la posición de la ventana flotante
            const { top, left, width, height } = img.getBoundingClientRect();
            let newTop = top + window.scrollY;
            let newLeft = left + width + 10 + window.scrollX;

            const viewportWidth = window.innerWidth;
            const viewportHeight = window.innerHeight;

            // Ajustar la posición para que no se salga por la derecha
            if (newLeft + ventanaFlotante.offsetWidth > viewportWidth) {
                newLeft = left - ventanaFlotante.offsetWidth - 10 + window.scrollX;
            }

            // Ajustar la posición para que no se salga por la parte inferior
            if (newTop + ventanaFlotante.offsetHeight > viewportHeight + window.scrollY) {
                newTop = top + height + window.scrollY - ventanaFlotante.offsetHeight - 10;
            }

            // Ajustar la posición para que no se salga por la parte superior
            if (newTop < window.scrollY) {
                newTop = window.scrollY + 10;
            }

            ventanaFlotante.style.top = `${newTop}px`;
            ventanaFlotante.style.left = `${newLeft}px`;
        };
    };

    // Ocultar ventana flotante
    const ocultarVentanaFlotante = () => {
        ventanaFlotante.style.display = 'none';
    };

    // Detectar imágenes en la página
    const detectarImagenes = () => {
        const images = document.querySelectorAll('img'); // Sólo imágenes <img> (no background-image)
        images.forEach((img) => {
            if (img.tagName === 'IMG') {
                img.addEventListener('mouseenter', ampliarImagen);
                img.addEventListener('mouseleave', ocultarVentanaFlotante);
            }
        });
    };

    // Llamar a la función para detectar imágenes
    detectarImagenes();

    // Añadir un observador de cambios en el DOM para detectar imágenes dinámicas
    const observer = new MutationObserver(detectarImagenes);
    observer.observe(document.body, { childList: true, subtree: true });
})();