|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- var pdfjsLib = window['pdfjs-dist/build/pdf'];
- pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.1.266/build/pdf.worker.min.js';
- class PdfRenderer {
- constructor(canvas) {
- this.numPages = 1;
- this.currentPage = 0;
- this.scale = 2;
-
- this.canvas = canvas;
- this.ctx = this.canvas.getContext("2d");
- this.offScreenCanvas = document.createElement("canvas");
- this.offScreenCtx = this.offScreenCanvas.getContext("2d");
- this.dpr = window.devicePixelRatio || 1;
- this.pdf = null;
- this.rendering = false;
- this.renderPending = false;
- }
-
- update(b64, cb) {
- if (b64 == "") {
- this.pdf = null;
- this.numPages = 1;
- this.currentPage = 0;
- this.render();
- cb();
- return;
- } else if (b64 == null) {
- cb();
- return;
- }
-
- let data = atob(b64);
-
- let loadingTask = pdfjsLib.getDocument({ data });
- loadingTask.promise.then(pdf => {
- this.pdf = pdf;
- this.numPages = this.pdf.numPages;
- if (this.currentPage >= this.numPages)
- this.currentPage = this.numPages - 1;
-
- this.render();
- cb();
- });
- }
-
- render() {
- if (this.rendering) {
- this.renderPending = true;
- return;
- }
-
- if (this.pdf == null) {
- this.canvas.width = this.canvas.width;
- return;
- }
-
- this.rendering = true;
- this.pdf.getPage(this.currentPage + 1).then(page => {
- let viewport = page.getViewport({ scale: this.scale });
- this.offScreenCanvas.height = viewport.height * this.dpr;
- this.offScreenCanvas.width = viewport.width * this.dpr;
- this.offScreenCanvas.style.width = viewport.width + "px";
- this.offScreenCanvas.style.height = viewport.height + "px";
- this.offScreenCtx.scale(this.dpr, this.dpr);
-
- let renderTask = page.render({ canvasContext: this.offScreenCtx, viewport });
- renderTask.promise.then(() => {
- this.canvas.width = this.offScreenCanvas.width;
- this.canvas.height = this.offScreenCanvas.height;
- this.canvas.style.width = this.offScreenCanvas.style.width;
- this.canvas.style.height = this.offScreenCanvas.style.height;
- this.ctx.drawImage(this.offScreenCanvas, 0, 0);
-
- this.rendering = false;
- if (this.renderPending) {
- this.renderPending = false;
- this.render();
- }
- });
- });
- }
- }
-
- let renderer = new PdfRenderer(document.getElementById("preview"));
- let previewState = document.getElementById("preview-state");
- let renderOutput = document.getElementById("pandoc-output");
-
- function updatePreviewState() {
- previewState.innerText = (renderer.currentPage + 1) + "/" + renderer.numPages;
- }
-
- let markdownReqNum = 0;
- let markdownReqLast = 0;
- function renderMarkdown(canvas, text) {
- let num = markdownReqNum++;
- fetch("/pandoc", {
- method: "POST",
- body: editor.value(),
- }).then(res => res.json()).then(obj => {
- if (num < markdownReqLast)
- return;
- markdownReqLast = num;
- renderOutput.innerText = obj.output;
-
- renderer.update(obj.pdf, () => {
- updatePreviewState();
- });
- });
- }
-
- function nextPage() {
- if (renderer.currentPage < renderer.numPages - 1) {
- renderer.currentPage += 1;
- renderer.render();
- updatePreviewState();
- }
- }
-
- function prevPage() {
- if (renderer.currentPage > 0) {
- renderer.currentPage -= 1;
- renderer.render();
- updatePreviewState();
- }
- }
-
- function debounce(ms, cb) {
- let timeout = null;
-
- return function() {
- if (timeout != null) {
- clearTimeout(timeout);
- timout = null;
- }
-
- timeout = setTimeout(cb, ms);
- }
- }
-
- let editor = new SimpleMDE({
- element: document.getElementById("editor"),
- hideIcons: [ "side-by-side", "preview" ],
- spellChecker: false,
- autosave: true,
- });
-
- let onChange = debounce(100, () => renderMarkdown(preview, editor.value()));
- editor.codemirror.on("change", onChange);
- renderMarkdown(preview, editor.value());
-
- document.getElementById("preview-prev-btn").addEventListener("click", prevPage);
- document.getElementById("preview-next-btn").addEventListener("click", nextPage);
|