Greasy Fork

YNJN Full-Page Large-Images Only

Descarga solo las imágenes grandes (por dimensión) de un capítulo en YNJN

目前为 2025-02-19 提交的版本。查看 最新版本

// ==UserScript==
// @name         YNJN Full-Page Large-Images Only
// @namespace    ynjn-downloader
// @version      1.1
// @description  Descarga solo las imágenes grandes (por dimensión) de un capítulo en YNJN
// @match        https://ynjn.jp/*
// @require      https://cdn.jsdelivr.net/npm/jszip@3/dist/jszip.min.js
// @require      https://cdn.jsdelivr.net/npm/file-saver@2/dist/FileSaver.min.js
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Esperar a que la página cargue por completo
    function waitForPageLoad(callback) {
        if (document.readyState === 'complete') {
            callback();
        } else {
            window.addEventListener('load', callback);
        }
    }

    waitForPageLoad(() => {
        console.log("📥 [YNJN Downloader] Script activo (solo imágenes grandes).");

        // Crear botón flotante
        const downloadBtn = document.createElement('button');
        downloadBtn.textContent = 'Descargar Solo Imágenes Grandes';
        downloadBtn.style.cssText = `
            position: fixed;
            top: 10px;
            right: 10px;
            z-index: 9999;
            background: #6e8efb;
            color: #fff;
            padding: 8px 12px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        `;
        document.body.appendChild(downloadBtn);

        downloadBtn.addEventListener('click', async () => {
            downloadBtn.disabled = true;
            downloadBtn.textContent = 'Cargando imágenes...';

            // 1. Hacer auto-scroll para forzar la carga (lazy load)
            await autoScroll();

            // 2. Recolectar solo imágenes grandes
            const largeImgs = gatherLargeImages(500, 500); 
            // Ajusta 500, 500 según necesites (ancho, alto)

            if (!largeImgs.length) {
                alert('⚠️ No se encontraron imágenes grandes. Asegúrate de haber hecho scroll hasta el final.');
                resetButton();
                return;
            }

            // 3. Descargar y crear ZIP
            try {
                await downloadAsZip(largeImgs);
            } catch (err) {
                console.error('❌ Error al descargar imágenes:', err);
                alert('⚠️ Error al descargar. Revisa la consola (F12) para más detalles.');
            }

            resetButton();
        });
    });

    /**
     * Desplazamiento automático para cargar imágenes lazy
     */
    async function autoScroll() {
        return new Promise(resolve => {
            let totalHeight = 0;
            const distance = 500;
            const timer = setInterval(() => {
                const scrollTopBefore = document.documentElement.scrollTop;
                window.scrollBy(0, distance);
                totalHeight += distance;

                // Si no avanzó más o llegamos al final, paramos
                if (document.documentElement.scrollTop === scrollTopBefore ||
                    (window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
                    clearInterval(timer);
                    // Esperar un poco extra para que terminen de cargar
                    setTimeout(resolve, 1000);
                }
            }, 400);
        });
    }

    /**
     * Recolectar imágenes solo si son grandes (por dimensiones)
     * @param {number} minWidth  - ancho mínimo
     * @param {number} minHeight - alto mínimo
     * @returns {string[]}       - array de URLs de imágenes grandes
     */
    function gatherLargeImages(minWidth, minHeight) {
        const imgs = Array.from(document.querySelectorAll('img'));
        const large = [];

        for (const img of imgs) {
            // Si la imagen está realmente cargada, podemos ver su tamaño
            // (naturalWidth/Height)
            if (img.naturalWidth >= minWidth && img.naturalHeight >= minHeight) {
                large.push(img.src);
            }
        }

        // Eliminar duplicados
        return Array.from(new Set(large));
    }

    /**
     * Descargar imágenes en un ZIP
     */
    async function downloadAsZip(urls) {
        const zip = new JSZip();

        for (let i = 0; i < urls.length; i++) {
            const url = urls[i];
            console.log(`📄 Descargando (${i+1}/${urls.length}):`, url);
            try {
                const resp = await fetch(url);
                const blob = await resp.blob();
                // Nombre con 3 dígitos
                zip.file(`${String(i+1).padStart(3, '0')}.jpg`, blob);
            } catch (err) {
                console.error(`Error al descargar ${url}:`, err);
            }
        }

        const zipContent = await zip.generateAsync({ type: 'blob' });
        saveAs(zipContent, 'ynjn_manga_big_images.zip');
        alert(`✅ Descarga completa: ${urls.length} imágenes grandes.`);
    }

    function resetButton() {
        const btn = document.querySelector('button');
        if (btn) {
            btn.disabled = false;
            btn.textContent = 'Descargar Solo Imágenes Grandes';
        }
    }
})();