parent
bf5dafda2d
commit
74ce9edfa9
@ -0,0 +1,118 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {PdfEstado} from "../../types/pdf_types";
|
||||||
|
import PdfPopup from "./PdfPopup.svelte";
|
||||||
|
import { jsPDF} from "jspdf";
|
||||||
|
import { pdfImages } from "../../data/data_pdfs_b64";
|
||||||
|
import { renderImages } from "../../data/data_images.b64";
|
||||||
|
import {imagesNames} from "../stores/sel.svelte";
|
||||||
|
|
||||||
|
|
||||||
|
let pdfEstado : PdfEstado = 'idle';
|
||||||
|
let pdfVisible = false;
|
||||||
|
let pdfMensaje = '';
|
||||||
|
|
||||||
|
async function generatePdf() {
|
||||||
|
pdfVisible = true;
|
||||||
|
pdfEstado = 'uploading';
|
||||||
|
const imageNames = imagesNames();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const pdfDoc = new jsPDF({
|
||||||
|
orientation: 'landscape',
|
||||||
|
unit: 'mm',
|
||||||
|
format: 'a4',
|
||||||
|
});
|
||||||
|
|
||||||
|
const pageWidth = pdfDoc.internal.pageSize.getWidth();
|
||||||
|
const pageHeight = pdfDoc.internal.pageSize.getHeight();
|
||||||
|
const margin = 15;
|
||||||
|
|
||||||
|
// === Portada ===
|
||||||
|
const ini = pdfImages['pdf_quaddro_ini'];
|
||||||
|
if (ini) {
|
||||||
|
const iniFormat = ini.includes('jpeg') ? 'JPEG' : 'PNG';
|
||||||
|
pdfDoc.addImage(ini, iniFormat, 0, 0, pageWidth, pageHeight, '', 'FAST');
|
||||||
|
pdfDoc.addPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Imágenes del array ===
|
||||||
|
imageNames.forEach((name, index) => {
|
||||||
|
const base64 = renderImages[name];
|
||||||
|
if (!base64) {
|
||||||
|
console.log('no existe la imagen ', name)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Datos de la imagen original
|
||||||
|
const imgPixelWidth = 1500;
|
||||||
|
const imgPixelHeight = 1500;
|
||||||
|
const pageRatio = pageWidth / pageHeight;
|
||||||
|
const imgRatio = imgPixelWidth / imgPixelHeight;
|
||||||
|
|
||||||
|
// Calcular tamaño para que mantenga proporción y ajuste a la altura de página
|
||||||
|
let renderWidth: number;
|
||||||
|
let renderHeight: number;
|
||||||
|
|
||||||
|
if (imgRatio > pageRatio) {
|
||||||
|
// Imagen más ancha que alta → ajustamos al alto
|
||||||
|
renderHeight = pageHeight - 2 * margin;
|
||||||
|
renderWidth = renderHeight * imgRatio;
|
||||||
|
} else {
|
||||||
|
// Imagen más alta → también ajustamos al alto
|
||||||
|
renderHeight = pageHeight - 2 * margin;
|
||||||
|
renderWidth = renderHeight * imgRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Posición alineada a la izquierda con margen de 15 mm
|
||||||
|
const x = margin;
|
||||||
|
const y = (pageHeight - renderHeight) / 2;
|
||||||
|
|
||||||
|
pdfDoc.addImage(base64, 'JPEG', x, y, renderWidth, renderHeight, '', 'FAST');
|
||||||
|
|
||||||
|
// Añadir nueva página excepto en la última
|
||||||
|
if (index < imageNames.length - 1) pdfDoc.addPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
// === Página final ===
|
||||||
|
pdfDoc.addPage();
|
||||||
|
const fin = pdfImages['pdf_quaddro_fin'];
|
||||||
|
if (fin) {
|
||||||
|
const finFormat = fin.includes('jpeg') ? 'JPEG' : 'PNG';
|
||||||
|
pdfDoc.addImage(fin, finFormat, 0, 0, pageWidth, pageHeight, '', 'FAST');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//pdfDoc.save(proyecto.textos.nombre_pdf ?? 'mi_seleccion.pdf');
|
||||||
|
|
||||||
|
pdfEstado = 'success'
|
||||||
|
|
||||||
|
} catch (err: any) {
|
||||||
|
pdfEstado = 'error';
|
||||||
|
pdfMensaje = err?.message || 'Error desconocido';
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
pdfVisible = false;
|
||||||
|
pdfEstado = 'idle';
|
||||||
|
}, 2500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<button type="button"
|
||||||
|
class="px-3 lg:px-4 py-2 rounded-md text-base font-medium transition-colors duration-200 text-white bg-green-900 hover:bg-green-700 cursor-pointer transition"
|
||||||
|
onclick={() => generatePdf()}>
|
||||||
|
Descargar Selección
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<PdfPopup {pdfVisible} {pdfMensaje} {pdfEstado} />
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { fade, scale } from 'svelte/transition';
|
||||||
|
import type {PdfEstado} from "../../types/pdf_types";
|
||||||
|
import {cubicOut} from "svelte/easing";
|
||||||
|
|
||||||
|
|
||||||
|
let { pdfVisible, pdfEstado, pdfMensaje } = $props< {
|
||||||
|
pdfEstado: PdfEstado;
|
||||||
|
pdfVisible: boolean;
|
||||||
|
pdfMensaje: string ;
|
||||||
|
}> ();
|
||||||
|
|
||||||
|
console.log('Pdf Poop',pdfVisible);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
{#if pdfVisible}
|
||||||
|
<!-- Fondo oscuro con fundido -->
|
||||||
|
<div
|
||||||
|
transition:fade={{ duration: 200, easing: cubicOut }}
|
||||||
|
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
|
||||||
|
>
|
||||||
|
<!-- Contenedor del popup con entrada tipo zoom -->
|
||||||
|
<div
|
||||||
|
transition:scale={{ duration: 250, easing: cubicOut }}
|
||||||
|
class="bg-white rounded-2xl p-8 w-100 text-center shadow-xl"
|
||||||
|
>
|
||||||
|
{#if pdfEstado === 'loading'}
|
||||||
|
<div class="flex flex-col items-center space-y-4">
|
||||||
|
<div class="w-10 h-10 border-4 border-gray-300 border-t-blue-500 rounded-full animate-spin"></div>
|
||||||
|
<p class="text-gray-700">Generando PDF...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{:else if pdfEstado === 'success'}
|
||||||
|
<div class="text-green-600 text-lg font-semibold">
|
||||||
|
✅ PDF generado correctamente
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{:else if pdfEstado === 'error'}
|
||||||
|
<div class="text-red-600 text-lg font-semibold">
|
||||||
|
❌ Error al generar PDF
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-600 text-sm mt-2">{pdfMensaje}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export type PdfEstado = 'idle' | 'uploading' | 'success' | 'error'
|
||||||
Loading…
Reference in new issue