feat: improved printing settings
This commit is contained in:
+46
-18
@@ -38,44 +38,72 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Al exportar/imprimir, solo se muestra #panel-output (y no sus propios
|
/* Al exportar/imprimir, solo se muestra #panel-output (y no sus propios
|
||||||
controles, marcados con .no-print), ocultando el resto de la página. */
|
controles, ni el resto de la página), todo ello marcado con .no-print
|
||||||
|
(#panel-top, la cabecera, las pestañas, "Personalización de página",
|
||||||
|
el título "Vista previa"...).
|
||||||
|
Se usa display:none (no visibility:hidden) para ocultarlo: un elemento
|
||||||
|
en visibility:hidden sigue ocupando su espacio en el documento, así que
|
||||||
|
con eso todo el contenido oculto (secciones, botones...) seguía
|
||||||
|
contando para la altura total y generaba varias páginas en blanco de
|
||||||
|
más al imprimir. */
|
||||||
@media print {
|
@media print {
|
||||||
body * {
|
.no-print {
|
||||||
visibility: hidden;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@page { margin: 0; }
|
@page { margin: 0; }
|
||||||
|
|
||||||
|
/* Pinta toda la hoja (no solo la caja de #panel-output, que puede
|
||||||
|
quedarse más corta que la página) con el color de fondo elegido en
|
||||||
|
"Personalización de página". La variable la actualiza
|
||||||
|
page-settings.js; aquí no se toca nada más de <html>/<body> para no
|
||||||
|
afectar a la pantalla de edición, solo a la impresión. */
|
||||||
|
html,
|
||||||
|
body,
|
||||||
#panel-output,
|
#panel-output,
|
||||||
#panel-output * {
|
#panel-output * {
|
||||||
visibility: visible;
|
|
||||||
/* Los navegadores no imprimen colores de fondo por defecto (dependen de
|
/* Los navegadores no imprimen colores de fondo por defecto (dependen de
|
||||||
la opción "Gráficos de fondo" del diálogo de impresión, que el
|
la opción "Gráficos de fondo" del diálogo de impresión, que el
|
||||||
usuario puede tener desmarcada); esto fuerza a respetar los colores
|
usuario puede tener desmarcada); esto fuerza a respetar los colores
|
||||||
elegidos en una sección de "Nota" aunque esa opción esté desactivada. */
|
elegidos en una sección de "Nota" (y el fondo de página) aunque esa
|
||||||
|
opción esté desactivada. */
|
||||||
-webkit-print-color-adjust: exact;
|
-webkit-print-color-adjust: exact;
|
||||||
print-color-adjust: exact;
|
print-color-adjust: exact;
|
||||||
}
|
}
|
||||||
|
|
||||||
#panel-output .no-print {
|
html,
|
||||||
display: none;
|
body {
|
||||||
|
/* Si no queda un poco de espacio en blanco al final del documento
|
||||||
|
cuando el contenido no llena una página entera: <html> es el
|
||||||
|
elemento "raíz" y su fondo (si lo tiene) es el que se usa para
|
||||||
|
rellenar toda la hoja (por delante del de <body>), así que Tailwind
|
||||||
|
o daisyUI podían estar aplicándole ya un color propio con más peso
|
||||||
|
que esta regla; !important fuerza a que gane siempre el elegido
|
||||||
|
aquí, tanto en <html> como en <body>. */
|
||||||
|
background-color: var(--print-page-bg-color, #ffffff) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Firefox no siempre extiende el fondo de <html>/<body> más allá de su
|
||||||
|
contenido cuando este no llena una página entera (a diferencia de
|
||||||
|
Chrome, que sí lo hace); para no depender de eso, se fuerza a que la
|
||||||
|
propia caja de #panel-output mida al menos una página de alto, así su
|
||||||
|
propio fondo (el mismo color, ya aplicado en JS) cubre ese hueco
|
||||||
|
también en Firefox. */
|
||||||
#panel-output {
|
#panel-output {
|
||||||
position: absolute;
|
min-height: 100vh;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
/* @page tiene margin: 0 (ver más abajo), así que sin esto el contenido
|
/* Por defecto el padding de una caja que ocupa varias páginas solo se
|
||||||
llegaría hasta el borde físico de la hoja. Se pone aquí (como
|
aplica una vez, al principio y al final de toda la caja (no en cada
|
||||||
padding del propio contenido) en vez de en @page porque el soporte
|
página); box-decoration-break: clone hace que cada fragmento (cada
|
||||||
de "margin" en @page es más inconsistente entre navegadores. */
|
página) se trate como una caja independiente con su propia copia del
|
||||||
|
padding, así el hueco queda igual en todas las páginas. Se hace así
|
||||||
|
(en vez de con @page margin) porque @page margin puede quedar
|
||||||
|
invalidado por el propio ajuste de "Márgenes" del diálogo de
|
||||||
|
impresión del navegador si el usuario no lo deja en "Predeterminado".*/
|
||||||
padding: 2cm;
|
padding: 2cm;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
-webkit-box-decoration-break: clone;
|
||||||
|
box-decoration-break: clone;
|
||||||
#preview-title {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -110,7 +110,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-col md:flex-row gap-4">
|
<div class="flex flex-col md:flex-row gap-4">
|
||||||
|
|
||||||
<section id="panel-top" class="w-full md:w-1/2 border border-base-300 rounded-box p-4">
|
<section id="panel-top" class="w-full md:w-1/2 border border-base-300 rounded-box p-4 no-print">
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between mb-2">
|
||||||
<h2 class="text-lg font-semibold">Secciones</h2>
|
<h2 class="text-lg font-semibold">Secciones</h2>
|
||||||
<button id="toggle-collapse-all" type="button" class="btn btn-xs btn-outline"
|
<button id="toggle-collapse-all" type="button" class="btn btn-xs btn-outline"
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="panel-output" class="w-full md:w-1/2 border border-base-300 rounded-box p-4 panel-hidden-mobile">
|
<section id="panel-output" class="w-full md:w-1/2 border border-base-300 rounded-box p-4 panel-hidden-mobile">
|
||||||
<h2 id="preview-title" class="text-lg font-semibold mb-2">Vista previa</h2>
|
<h2 id="preview-title" class="text-lg font-semibold mb-2 no-print">Vista previa</h2>
|
||||||
<div id="panel-output-text" class="text-sm"
|
<div id="panel-output-text" class="text-sm"
|
||||||
data-empty-message="Añade una sección para ver aquí el resultado."></div>
|
data-empty-message="Añade una sección para ver aquí el resultado."></div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -28,6 +28,15 @@ export function renderPageMeta() {
|
|||||||
panelOutput.style.fontFamily = pageFontSelect.value;
|
panelOutput.style.fontFamily = pageFontSelect.value;
|
||||||
pageSizeStyle.textContent = `@page { size: ${pageSizeSelect.value} ${pageOrientationSelect.value}; }`;
|
pageSizeStyle.textContent = `@page { size: ${pageSizeSelect.value} ${pageOrientationSelect.value}; }`;
|
||||||
document.title = pageTitleInput.value.trim() || 'Crochet';
|
document.title = pageTitleInput.value.trim() || 'Crochet';
|
||||||
|
|
||||||
|
// El color de fondo también se guarda en una variable CSS en :root, para
|
||||||
|
// que css/main.css pueda pintar con él toda la hoja al imprimir (no solo
|
||||||
|
// la caja de #panel-output, que puede quedarse más corta que la página).
|
||||||
|
// Se hace así, en vez de aplicar el color directamente a <body>, para no
|
||||||
|
// cambiar también el fondo de toda la pantalla de edición: la variable no
|
||||||
|
// pinta nada por sí sola en pantalla, solo la consume la regla @media
|
||||||
|
// print de más abajo.
|
||||||
|
document.documentElement.style.setProperty('--print-page-bg-color', pageBgColorInput.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function serializePageSettings() {
|
export function serializePageSettings() {
|
||||||
|
|||||||
+6
-1
@@ -250,7 +250,7 @@ const SECTION_TYPES = [
|
|||||||
if (!img.src || img.classList.contains('hidden')) return;
|
if (!img.src || img.classList.contains('hidden')) return;
|
||||||
const clone = document.createElement('img');
|
const clone = document.createElement('img');
|
||||||
clone.src = img.src;
|
clone.src = img.src;
|
||||||
clone.className = 'max-w-full max-h-48 object-contain rounded-box my-2';
|
clone.className = 'max-w-full max-h-96 object-contain rounded-box my-2';
|
||||||
target.appendChild(clone);
|
target.appendChild(clone);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -357,8 +357,13 @@ export function buildSectionsFrom(sectionsData, container = sectionsContainer) {
|
|||||||
// mismo mecanismo que restaura un patrón guardado.
|
// mismo mecanismo que restaura un patrón guardado.
|
||||||
const DEFAULT_SECTIONS = [
|
const DEFAULT_SECTIONS = [
|
||||||
{ type: 'image', dataUrl: '' },
|
{ type: 'image', dataUrl: '' },
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
children: [
|
||||||
{ type: 'title', text: {} },
|
{ type: 'title', text: {} },
|
||||||
{ type: 'materials', materials: [] },
|
{ type: 'materials', materials: [] },
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'group',
|
type: 'group',
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
+6
-2
@@ -97,7 +97,11 @@ export function createSectionShell(typeLabel) {
|
|||||||
// un nombre derivado del contenido ("Título: Bufanda de lana") sin perder
|
// un nombre derivado del contenido ("Título: Bufanda de lana") sin perder
|
||||||
// de vista cuál es la etiqueta de tipo original.
|
// de vista cuál es la etiqueta de tipo original.
|
||||||
const badge = document.createElement('span');
|
const badge = document.createElement('span');
|
||||||
badge.className = 'section-badge badge badge-sm badge-outline select-none';
|
// 'min-w-0 truncate': por defecto un elemento flex no encoge por debajo
|
||||||
|
// del tamaño de su contenido, así que un nombre largo (p.ej. una lista de
|
||||||
|
// materiales) desbordaba la cabecera en pantallas estrechas en vez de
|
||||||
|
// recortarse con "…".
|
||||||
|
badge.className = 'section-badge badge badge-sm badge-outline select-none min-w-0 truncate';
|
||||||
badge.textContent = typeLabel;
|
badge.textContent = typeLabel;
|
||||||
badge.dataset.typeLabel = typeLabel;
|
badge.dataset.typeLabel = typeLabel;
|
||||||
|
|
||||||
@@ -318,7 +322,7 @@ export function addImageSection(data, dataUrl = '', container = sectionsContaine
|
|||||||
fileInput.className = 'file-input file-input-bordered w-full mb-2';
|
fileInput.className = 'file-input file-input-bordered w-full mb-2';
|
||||||
|
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.className = 'max-w-full max-h-48 object-contain rounded-box hidden';
|
img.className = 'max-w-full max-h-96 object-contain rounded-box hidden';
|
||||||
|
|
||||||
if (dataUrl) {
|
if (dataUrl) {
|
||||||
img.src = dataUrl;
|
img.src = dataUrl;
|
||||||
|
|||||||
Reference in New Issue
Block a user