Zoom on Hover

Zoom on Hover enlarges images when you hover over them.

当前为 2024-11-25 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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 });
})();