Prevent total lockup when generating PDF, show status updates during generation
This commit is contained in:
parent
367daeca57
commit
4609cc114f
@ -100,7 +100,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="btn-toolbar" role="toolbar">
|
<div class="btn-toolbar d-inline-block" role="toolbar">
|
||||||
<div class="btn-group me-2 mb-2" role="group" aria-label="First group">
|
<div class="btn-group me-2 mb-2" role="group" aria-label="First group">
|
||||||
<div class="btn btn-primary" onclick="addPDF();"><i class="fas fa-file-pdf"></i> Add PDF</div>
|
<div class="btn btn-primary" onclick="addPDF();"><i class="fas fa-file-pdf"></i> Add PDF</div>
|
||||||
<div class="btn btn-primary" onclick="savePDF();"><i class="fas fa-save"></i> Save Signed PDF</div>
|
<div class="btn btn-primary" onclick="savePDF();"><i class="fas fa-save"></i> Save Signed PDF</div>
|
||||||
@ -108,6 +108,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
<div class="btn btn-primary" onclick="openSettingsModal();"><i class="fas fa-cog"></i> Settings</div>
|
<div class="btn btn-primary" onclick="openSettingsModal();"><i class="fas fa-cog"></i> Settings</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="statustext" class="d-inline-block"></div>
|
||||||
<div class="btn-toolbar" role="toolbar">
|
<div class="btn-toolbar" role="toolbar">
|
||||||
<div class="btn-group me-2 mb-2" role="group" aria-label="First group">
|
<div class="btn-group me-2 mb-2" role="group" aria-label="First group">
|
||||||
<div class="btn btn-primary" onclick="pdfZoom('fitheight');"><i class="fas fa-arrows-alt-v"></i> Fit Height</div>
|
<div class="btn btn-primary" onclick="pdfZoom('fitheight');"><i class="fas fa-arrows-alt-v"></i> Fit Height</div>
|
||||||
@ -139,7 +140,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
<script src="node_modules/pdfjs-dist/build/pdf.min.js"></script>
|
<script src="node_modules/pdfjs-dist/build/pdf.min.js"></script>
|
||||||
<script src="node_modules/jspdf/dist/jspdf.umd.min.js"></script>
|
<script src="node_modules/jspdf/dist/jspdf.umd.min.js"></script>
|
||||||
<script src="node_modules/signature_pad/dist/signature_pad.umd.min.js"></script>
|
<script src="node_modules/signature_pad/dist/signature_pad.umd.min.js"></script>
|
||||||
<script src="node_modules/jshashes/hashes.min.js"></script>
|
|
||||||
<script src="js/kbpgp-2.1.15.js"></script>
|
<script src="js/kbpgp-2.1.15.js"></script>
|
||||||
<script src="js/svg-to-image.js"></script>
|
<script src="js/svg-to-image.js"></script>
|
||||||
<script src="js/util.js"></script>
|
<script src="js/util.js"></script>
|
||||||
|
55
js/pdf.js
55
js/pdf.js
@ -40,8 +40,10 @@ function closePDF(showuserconfirm) {
|
|||||||
$("#page-canvas-container .page-canvas").remove();
|
$("#page-canvas-container .page-canvas").remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePDF() {
|
function generatePDF(callback) {
|
||||||
var canvases = $("#page-canvas-container .page-canvas");
|
var canvases = $("#page-canvas-container .page-canvas");
|
||||||
|
var statustextEl = $("#statustext");
|
||||||
|
statustextEl.html("<i class='fas fa-spin fa-spinner'></i> Processing document...");
|
||||||
const pdf = new jsPDF({
|
const pdf = new jsPDF({
|
||||||
unit: "in",
|
unit: "in",
|
||||||
compress: true
|
compress: true
|
||||||
@ -49,19 +51,32 @@ function generatePDF() {
|
|||||||
// creating a PDF creates a blank page that we don't want to use,
|
// creating a PDF creates a blank page that we don't want to use,
|
||||||
// as we haven't done the calculations yet
|
// as we haven't done the calculations yet
|
||||||
pdf.deletePage(1);
|
pdf.deletePage(1);
|
||||||
for (var i = 0; i < canvases.length; i++) {
|
|
||||||
var canvas = $("#page-canvas-container .page-canvas")[i];
|
// Render each page in order with a pause in between to keep UI responsive
|
||||||
var widthpx = canvas.getContext("2d").canvas.width;
|
var processPage = function (i) {
|
||||||
var heightpx = canvas.getContext("2d").canvas.height;
|
if (i < canvases.length) {
|
||||||
var pageWidthInches = widthpx / (pdfAssumedDPI * pdfPageScale);
|
statustextEl.html("<i class='fas fa-spin fa-spinner'></i> Processing page " + (i + 1) + " of " + canvases.length + "...");
|
||||||
var pageHeightInches = heightpx / (pdfAssumedDPI * pdfPageScale);
|
console.log("Processing " + (i + 1));
|
||||||
console.log(pageWidthInches + " x " + pageHeightInches);
|
var canvas = canvases[i];
|
||||||
var pageFormat = [pageWidthInches, pageHeightInches];
|
var widthpx = canvas.getContext("2d").canvas.width;
|
||||||
var pageOrientation = (pageWidthInches > pageHeightInches ? "landscape" : "portrait");
|
var heightpx = canvas.getContext("2d").canvas.height;
|
||||||
pdf.addPage(pageFormat, pageOrientation);
|
var pageWidthInches = widthpx / (pdfAssumedDPI * pdfPageScale);
|
||||||
pdf.addImage($("#page-canvas-container .page-canvas")[i].toDataURL(), 0, 0, pageWidthInches, pageHeightInches);
|
var pageHeightInches = heightpx / (pdfAssumedDPI * pdfPageScale);
|
||||||
|
console.log(pageWidthInches + " x " + pageHeightInches);
|
||||||
|
var pageFormat = [pageWidthInches, pageHeightInches];
|
||||||
|
var pageOrientation = (pageWidthInches > pageHeightInches ? "landscape" : "portrait");
|
||||||
|
pdf.addPage(pageFormat, pageOrientation);
|
||||||
|
pdf.addImage(canvases[i].toDataURL(), 0, 0, pageWidthInches, pageHeightInches);
|
||||||
|
i++;
|
||||||
|
setTimeout(function () {
|
||||||
|
processPage(i)
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
statustextEl.html("");
|
||||||
|
callback(pdf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return pdf;
|
processPage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPDFAsByteArray(pdf) {
|
function getPDFAsByteArray(pdf) {
|
||||||
@ -93,15 +108,23 @@ function makeAndSaveSignedPDF(pdf, savepath, callback) {
|
|||||||
|
|
||||||
function savePDF() {
|
function savePDF() {
|
||||||
disableGuideBox();
|
disableGuideBox();
|
||||||
|
var statustextEl = $("#statustext");
|
||||||
loadKeyFromLocalStorage(function (message, ok) {
|
loadKeyFromLocalStorage(function (message, ok) {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
openSaveFileDialog(function (path) {
|
openSaveFileDialog(function (path) {
|
||||||
var pdf = generatePDF();
|
generatePDF(function (pdf) {
|
||||||
makeAndSaveSignedPDF(pdf, path, function (result) {
|
statustextEl.html("<i class='fas fa-spin fa-spinner'></i> Signing document...");
|
||||||
alert("File signed and saved.\n SHA256 of file (without signature): " + result.hash);
|
makeAndSaveSignedPDF(pdf, path, function (result) {
|
||||||
|
statustextEl.html("<i class='fas fa-check'></i> Signed and saved!");
|
||||||
|
alert("File signed and saved.\nSHA256 of file (without signature): " + result.hash);
|
||||||
|
setTimeout(function () {
|
||||||
|
statustextEl.html("");
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, "signed.pdf", ".pdf");
|
}, "signed.pdf", ".pdf");
|
||||||
} else {
|
} else {
|
||||||
|
statustextEl.html("");
|
||||||
alert("Error: " + message);
|
alert("Error: " + message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user