Greasy Fork

Greasy Fork is available in English.

Yanmaga Manga Full Page Capturer

Captura todas las páginas completas de manga en yanmaga.jp y permite descargarlas como ZIP desde una galeria visual flotante.

当前为 2025-06-17 提交的版本,查看 最新版本

// ==UserScript==
// @name         Yanmaga Manga Full Page Capturer
// @namespace    yanmaga-fullpage
// @version      1.6
// @description  Captura todas las páginas completas de manga en yanmaga.jp y permite descargarlas como ZIP desde una galeria visual flotante.
// @author       
// @license      MIT
// @match        https://yanmaga.jp/viewer/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const capturadas = [];

    const estilos = `
        #galeria-panel {
            position: fixed;
            top: 60px;
            left: 10px;
            width: 300px;
            max-height: 85vh;
            overflow-y: auto;
            background: #f9fafb;
            border: 2px solid #1e293b;
            padding: 10px;
            z-index: 9998;
            font-size: 12px;
        }
        #galeria-panel img {
            width: 100%;
            border: 1px solid #ccc;
        }
        #galeria-panel .item {
            margin-bottom: 10px;
        }
        #capturar-btn, #descargar-btn {
            position: fixed;
            top: 10px;
            left: 10px;
            z-index: 9999;
            background: #1e40af;
            color: white;
            padding: 10px 14px;
            margin-right: 6px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
        }
        #descargar-btn {
            left: 180px;
            background: #059669;
        }
    `;

    const styleTag = document.createElement('style');
    styleTag.innerHTML = estilos;
    document.head.appendChild(styleTag);

    const btnCapturar = document.createElement('button');
    btnCapturar.id = 'capturar-btn';
    btnCapturar.textContent = '📸 Capturar páginas';
    btnCapturar.onclick = capturar;
    document.body.appendChild(btnCapturar);

    const btnDescargar = document.createElement('button');
    btnDescargar.id = 'descargar-btn';
    btnDescargar.textContent = '⬇️ Descargar ZIP';
    btnDescargar.onclick = descargarZip;
    document.body.appendChild(btnDescargar);

    const galeria = document.createElement('div');
    galeria.id = 'galeria-panel';
    galeria.innerHTML = `<strong>📚 Imágenes Capturadas:</strong><div id="contenedor-imagenes"></div>`;
    document.body.appendChild(galeria);

    async function capturar() {
        const imagenes = [...document.querySelectorAll('img')];
        const candidatas = imagenes.filter(img => img.naturalHeight > 800 && img.naturalWidth > 400);

        for (let i = 0; i < candidatas.length; i++) {
            const img = candidatas[i];
            if (capturadas.find(x => x.url === img.src)) continue;

            const blob = await fetch(img.src).then(r => r.blob());
            const bitmap = await createImageBitmap(blob);
            const fileName = `pagina_${String(capturadas.length + 1).padStart(3, '0')}_${bitmap.width}x${bitmap.height}.jpg`;

            capturadas.push({ fileName, blob, url: img.src });

            const div = document.createElement('div');
            div.className = 'item';
            div.innerHTML = `<img src="${img.src}" /><div>${fileName}</div>`;
            document.getElementById('contenedor-imagenes').appendChild(div);
        }

        alert(`✅ Capturadas ${capturadas.length} páginas.`);
    }

    async function descargarZip() {
        if (capturadas.length === 0) return alert('⚠️ No hay imágenes capturadas.');
        const zip = new JSZip();
        capturadas.forEach(img => zip.file(img.fileName, img.blob));
        const contenido = await zip.generateAsync({ type: 'blob' });
        saveAs(contenido, 'manga_completo.zip');
    }
})();