117 lines
2.8 KiB
Vue
117 lines
2.8 KiB
Vue
|
|
<script setup>
|
||
|
|
import PagedJsWrapper from './components/PagedJsWrapper.vue';
|
||
|
|
import { onMounted, ref, nextTick } from 'vue';
|
||
|
|
import { Previewer } from 'pagedjs';
|
||
|
|
|
||
|
|
const marginTop = ref(20);
|
||
|
|
let sourceHTML = '';
|
||
|
|
let editorUIElement = null;
|
||
|
|
|
||
|
|
const renderPaged = async () => {
|
||
|
|
console.log('renderPaged called, marginTop:', marginTop.value);
|
||
|
|
|
||
|
|
// Update @page margin dynamically
|
||
|
|
let styleEl = document.getElementById('dynamic-page-style');
|
||
|
|
if (!styleEl) {
|
||
|
|
styleEl = document.createElement('style');
|
||
|
|
styleEl.id = 'dynamic-page-style';
|
||
|
|
document.head.appendChild(styleEl);
|
||
|
|
}
|
||
|
|
styleEl.textContent = `
|
||
|
|
@page {
|
||
|
|
size: A4;
|
||
|
|
margin: ${marginTop.value}mm 15mm 26mm 15mm;
|
||
|
|
}
|
||
|
|
`;
|
||
|
|
|
||
|
|
// Detach UI before PagedJS processes body
|
||
|
|
if (editorUIElement && editorUIElement.parentNode) {
|
||
|
|
editorUIElement.remove();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Remove previous render
|
||
|
|
const existingPages = document.querySelector('.pagedjs_pages');
|
||
|
|
if (existingPages) existingPages.remove();
|
||
|
|
|
||
|
|
// Restore source content to body
|
||
|
|
const printSource = document.getElementById('print-source');
|
||
|
|
if (printSource && sourceHTML) {
|
||
|
|
printSource.innerHTML = sourceHTML;
|
||
|
|
printSource.style.display = 'block';
|
||
|
|
}
|
||
|
|
|
||
|
|
// Render
|
||
|
|
const paged = new Previewer();
|
||
|
|
try {
|
||
|
|
const flow = await paged.preview();
|
||
|
|
console.log('Rendered', flow.total, 'pages.');
|
||
|
|
} catch (e) {
|
||
|
|
console.error('PagedJS error:', e);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Re-inject UI after PagedJS transforms the DOM
|
||
|
|
if (editorUIElement) {
|
||
|
|
document.body.appendChild(editorUIElement);
|
||
|
|
// Apply styles inline since PagedJS removes stylesheets
|
||
|
|
editorUIElement.style.cssText = `
|
||
|
|
position: fixed !important;
|
||
|
|
bottom: 1rem !important;
|
||
|
|
left: 1rem !important;
|
||
|
|
z-index: 9999 !important;
|
||
|
|
background: white;
|
||
|
|
padding: 0.5rem;
|
||
|
|
border-radius: 4px;
|
||
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||
|
|
`;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const increaseMargin = () => {
|
||
|
|
marginTop.value += 5;
|
||
|
|
console.log('Button clicked, new margin:', marginTop.value);
|
||
|
|
renderPaged();
|
||
|
|
};
|
||
|
|
|
||
|
|
onMounted(async () => {
|
||
|
|
await nextTick();
|
||
|
|
// Store source HTML before first render
|
||
|
|
const source = document.getElementById('print-source');
|
||
|
|
if (source) {
|
||
|
|
sourceHTML = source.innerHTML;
|
||
|
|
console.log('Source HTML stored:', sourceHTML.substring(0, 100));
|
||
|
|
}
|
||
|
|
// Store UI element reference
|
||
|
|
editorUIElement = document.getElementById('editor-ui');
|
||
|
|
renderPaged();
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<!-- Source content -->
|
||
|
|
<div id="print-source">
|
||
|
|
<PagedJsWrapper />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Editor UI overlay -->
|
||
|
|
<div id="editor-ui">
|
||
|
|
<button id="increase-margin" @click="increaseMargin">+</button>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<style>
|
||
|
|
/* PagedJS print styles */
|
||
|
|
h2 {
|
||
|
|
break-before: page;
|
||
|
|
}
|
||
|
|
|
||
|
|
@page {
|
||
|
|
@bottom-center {
|
||
|
|
content: string(title);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.chapter > h2 {
|
||
|
|
string-set: title content(text);
|
||
|
|
}
|
||
|
|
</style>
|