Restyled the sign page and cleaned up code in various places.
This commit is contained in:
parent
fc0af56136
commit
b2a29e2b13
16 changed files with 685 additions and 674 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -110,3 +110,5 @@ local.properties
|
|||
*.rar
|
||||
|
||||
/build
|
||||
|
||||
/.vscode
|
|
@ -42,3 +42,8 @@ html[lang-direction=rtl] * {
|
|||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.btn-group > label:first-of-type {
|
||||
border-top-left-radius: 0.25rem !important;
|
||||
border-bottom-left-radius: 0.25rem !important;
|
||||
}
|
||||
|
|
|
@ -108,16 +108,17 @@ function initializeGame() {
|
|||
}
|
||||
|
||||
|
||||
function resetEnemies() {
|
||||
function resetEnemies() {
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
pdfs.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateGame() {
|
||||
if (gameOver || paused) return;
|
||||
|
||||
pdfs.forEach((pdf, pdfIndex) => {
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
const pdfY = parseInt(pdf.style.top) + pdfSpeed;
|
||||
if (pdfY + 50 > gameContainer.clientHeight) {
|
||||
gameContainer.removeChild(pdf);
|
||||
|
@ -149,11 +150,7 @@ function resetEnemies() {
|
|||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
projectiles.forEach((projectile, projectileIndex) => {
|
||||
const projectileY = parseInt(projectile.style.top) - 10;
|
||||
|
@ -180,7 +177,8 @@ function resetEnemies() {
|
|||
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
}
|
||||
function resetGame() {
|
||||
|
||||
function resetGame() {
|
||||
playerX = gameContainer.clientWidth / 2;
|
||||
playerY = 50;
|
||||
updatePlayerPosition();
|
||||
|
@ -204,7 +202,7 @@ function resetGame() {
|
|||
clearTimeout(spawnPdfTimeout); // Clear the existing spawnPdfTimeout
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
spawnPdfInterval();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -243,9 +241,7 @@ function resetGame() {
|
|||
updateHighScore();
|
||||
}
|
||||
alert('Game Over! Your final score is: ' + score);
|
||||
setTimeout(() => { // Wrap the resetGame() call in a setTimeout
|
||||
resetGame();
|
||||
}, 0);
|
||||
document.getElementById('game-container-wrapper').close();
|
||||
}
|
||||
|
||||
|
||||
|
@ -281,6 +277,7 @@ function resetGame() {
|
|||
|
||||
});
|
||||
|
||||
window.resetGame = resetGame;
|
||||
}
|
||||
|
||||
window.initializeGame = initializeGame;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{PDFToHTML.title})}"></th:block>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{PDFToPresentation.title})}"></th:block>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{PDFToText.title})}"></th:block>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{PDFToWord.title})}"></th:block>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{PDFToXML.title})}"></th:block>
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -101,15 +101,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
</script>
|
||||
|
||||
</head>
|
||||
<th:block th:fragment="fileSelector(name, multiple)" th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}">
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
<th:block th:fragment="game">
|
||||
<dialog id="game-container-wrapper" class="game-container-wrapper" data-modal>
|
||||
<script>
|
||||
console.log("loaded game")
|
||||
$(document).ready(function() {
|
||||
|
||||
function loadGameScript(callback) {
|
||||
console.log('loadGameScript called');
|
||||
const script = document.createElement('script');
|
||||
|
@ -127,13 +124,79 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
window.initializeGame();
|
||||
gameScriptLoaded = true;
|
||||
});
|
||||
} else {
|
||||
window.resetGame();
|
||||
}
|
||||
$('#game-container-wrapper').show();
|
||||
document.getElementById('game-container-wrapper').showModal();
|
||||
});
|
||||
})
|
||||
</script>
|
||||
<div id="game-container">
|
||||
<div id="lives">Lives: 3</div>
|
||||
<div id="score">Score: 0</div>
|
||||
<div id="high-score">High Score: 0</div>
|
||||
<div id="level">Level: 1</div>
|
||||
<img src="favicon.svg" class="player" id="player">
|
||||
</div>
|
||||
<style>
|
||||
#game-container {
|
||||
position: relative;
|
||||
width: 100vh;
|
||||
height: 0;
|
||||
padding-bottom: 75%; /* 4:3 aspect ratio */
|
||||
background-color: transparent;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
border: 2px solid black; /* Add border */
|
||||
}
|
||||
|
||||
.pdf, .player, .projectile {
|
||||
position: absolute;
|
||||
}
|
||||
.pdf {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.player {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.projectile {
|
||||
background-color: black !important;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
}
|
||||
#score, #level, #lives, #high-score {
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
font-size: calc(14px + 0.25vw); /* Reduced font size */
|
||||
}
|
||||
#score {
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
#lives {
|
||||
top: 10px;
|
||||
left: calc(7vw); /* Adjusted position */
|
||||
}
|
||||
#high-score {
|
||||
top: 10px;
|
||||
left: calc(14vw); /* Adjusted position */
|
||||
}
|
||||
#level {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</dialog>
|
||||
</th:block>
|
||||
|
||||
<th:block th:fragment="fileSelector(name, multiple)" th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}">
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('form').submit(function(event) {
|
||||
|
||||
const boredWaiting = localStorage.getItem('boredWaiting');
|
||||
if (boredWaiting === 'enabled') {
|
||||
$('#show-game-btn').show();
|
||||
|
@ -392,23 +455,16 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
progressBar.css('width', progress + '%');
|
||||
progressBar.attr('aria-valuenow', parseInt(progressBar.attr('aria-valuenow')) + 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="custom-file-chooser">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" th:name="${name}" th:id="${name}+'-input'" th:accept="${accept}" multiple>
|
||||
<label class="custom-file-label" th:for="${name}+'-input'" th:text="${inputText}"></label>
|
||||
</div>
|
||||
<div class="selected-files"></div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
<br>
|
||||
<div id="progressBarContainer" style="display: none; position: relative;">
|
||||
<div class="progress" style="height: 1rem;">
|
||||
<div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
|
||||
|
@ -416,79 +472,13 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" id="show-game-btn" style="display:none;">Bored waiting?</button>
|
||||
|
||||
<div id="game-container-wrapper" class="game-container-wrapper" style="display: none;">
|
||||
<div id="game-container">
|
||||
<div id="lives">Lives: 3</div>
|
||||
<div id="score">Score: 0</div>
|
||||
<div id="high-score">High Score: 0</div>
|
||||
<div id="level">Level: 1</div>
|
||||
<img src="favicon.svg" class="player" id="player">
|
||||
</div>
|
||||
<style>
|
||||
#game-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 75%; /* 4:3 aspect ratio */
|
||||
background-color: transparent;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
border: 2px solid black; /* Add border */
|
||||
}
|
||||
|
||||
.pdf, .player, .projectile {
|
||||
position: absolute;
|
||||
}
|
||||
.pdf {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.player {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.projectile {
|
||||
background-color: black !important;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
}
|
||||
#score, #level, #lives, #high-score {
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
font-size: calc(14px + 0.25vw); /* Reduced font size */
|
||||
}
|
||||
#score {
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
#lives {
|
||||
top: 10px;
|
||||
left: calc(7vw); /* Adjusted position */
|
||||
}
|
||||
#high-score {
|
||||
top: 10px;
|
||||
left: calc(14vw); /* Adjusted position */
|
||||
}
|
||||
#level {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<button type="button" class="btn btn-primary" id="show-game-btn" style="display:none;">Bored waiting?</button>
|
||||
|
||||
|
||||
|
||||
<script th:inline="javascript">
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const fileInput = document.getElementById('fileInput-input');
|
||||
const fileInput = document.getElementById([[${name+"-input"}]]);
|
||||
|
||||
// Prevent default behavior for drag events
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
|
@ -509,10 +499,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
fileInput.files = files;
|
||||
handleFileInputChange(fileInput)
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
$([[${"#"+name+"-input"}]]).on("change", function() {
|
||||
handleFileInputChange(this);
|
||||
});
|
||||
|
@ -533,24 +521,19 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
} else {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html([[#{pdfPrompt}]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.custom-file-label {
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
.selected-files {
|
||||
}
|
||||
.selected-files {
|
||||
margin-top: 10px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</th:block>
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
|
|
@ -13,31 +13,40 @@
|
|||
<style>
|
||||
#pdf-container {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
#pdf-canvas {
|
||||
#pdf-canvas {
|
||||
border: 1px solid black;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#signature-canvas {
|
||||
#signature-canvas {
|
||||
border: 1px solid red;
|
||||
position: absolute;
|
||||
touch-action: none;
|
||||
top: 10px; /* Make sure this value matches the margin-top of #pdf-canvas */
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.signature-pad-container {
|
||||
#signature-pad-container {
|
||||
border: 1px solid black;
|
||||
display: none;
|
||||
margin-top: 10px;
|
||||
}
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
#signature-pad-canvas {
|
||||
background: rgba(125,125,125,0.2);
|
||||
}
|
||||
|
||||
#pdf-canvas {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common.html :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||
|
@ -46,20 +55,30 @@
|
|||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 th:text="#{extractImages.header}"></h2>
|
||||
<input type="file" id="pdf-upload" accept=".pdf" class="btn btn-outline-primary mb-2" />
|
||||
<input type="file" id="signature-upload" accept="image/*" class="btn btn-outline-primary mb-2" />
|
||||
<button id="toggle-draw-signature" class="btn btn-outline-primary mb-2">Draw signature</button>
|
||||
<button id="download-pdf" class="btn btn-outline-primary mb-2">Download PDF</button>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multiple=false, accept='application/pdf')}"></div>
|
||||
|
||||
<div class = "btn-group">
|
||||
<input type="radio" class="btn-check" name="signature-type" id="draw-signature" autocomplete="off" checked>
|
||||
<label class="btn btn-outline-secondary" for="draw-signature">Draw signature</label>
|
||||
<input type="radio" class="btn-check" name="signature-type" id="import-image" autocomplete="off">
|
||||
<label class="btn btn-outline-secondary" for="import-image">Import image</label>
|
||||
</div>
|
||||
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='signature-upload', multiple=false, accept='image/*', inputText=#{imgPrompt})}"></div>
|
||||
<!-- Signature Pad -->
|
||||
<div id="signature-pad-container">
|
||||
<canvas id="signature-pad-canvas"></canvas>
|
||||
<br>
|
||||
<button id="clear-signature" class="btn btn-outline-danger mt-2">Clear</button>
|
||||
<button id="save-signature" class="btn btn-outline-success mt-2">Save</button>
|
||||
</div>
|
||||
|
||||
<div id="pdf-container">
|
||||
<canvas id="pdf-canvas"></canvas>
|
||||
<canvas id="signature-canvas" hidden style="position: absolute;" data-scale="1"></canvas>
|
||||
</div>
|
||||
<!-- Signature Pad -->
|
||||
<div class="signature-pad-container">
|
||||
<canvas id="signature-pad-canvas"></canvas>
|
||||
<button id="clear-signature" class="btn btn-outline-danger mt-2">Clear</button>
|
||||
<button id="save-signature" class="btn btn-outline-success mt-2">Save</button>
|
||||
</div>
|
||||
|
||||
<button id="download-pdf" class="btn btn-primary mb-2">Download PDF</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,16 +87,18 @@
|
|||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const pdfUpload = document.getElementById('pdf-upload');
|
||||
const signatureUpload = document.getElementById('signature-upload');
|
||||
const pdfUpload = document.querySelector('input[name=pdf-upload]');
|
||||
const signatureUpload = document.querySelector('input[name=signature-upload]');
|
||||
const pdfCanvas = document.getElementById('pdf-canvas');
|
||||
const signatureCanvas = document.getElementById('signature-canvas');
|
||||
const downloadPdfBtn = document.getElementById('download-pdf');
|
||||
const toggleDrawSignatureBtn = document.getElementById('toggle-draw-signature');
|
||||
const signaturePadContainer = document.getElementById('signature-pad-container')
|
||||
const signaturePadCanvas = document.getElementById('signature-pad-canvas');
|
||||
const clearSignatureBtn = document.getElementById('clear-signature');
|
||||
const saveSignatureBtn = document.getElementById('save-signature');
|
||||
|
||||
document.querySelector('input[name=signature-upload]').closest(".custom-file-chooser").style.display = "none"
|
||||
|
||||
const signaturePad = new SignaturePad(signaturePadCanvas, {
|
||||
minWidth: 1,
|
||||
maxWidth: 2,
|
||||
|
@ -90,70 +111,33 @@
|
|||
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.12.313/pdf.worker.min.js';
|
||||
|
||||
async function loadPdf(pdfData) {
|
||||
pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
|
||||
renderPage(1);
|
||||
}
|
||||
|
||||
pdfUpload.addEventListener('change', async (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
const pdfData = await file.arrayBuffer();
|
||||
loadPdf(pdfData);
|
||||
pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
|
||||
renderPage(1);
|
||||
}
|
||||
});
|
||||
|
||||
signatureUpload.addEventListener('change', async (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const img = new Image();
|
||||
img.src = e.target.result;
|
||||
img.onload = () => {
|
||||
const ctx = signatureCanvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height);
|
||||
signatureCanvas.width = img.width;
|
||||
signatureCanvas.height = img.height;
|
||||
signatureCanvas.hidden = false;
|
||||
setTimeout(() => {
|
||||
const x = 0;
|
||||
const y = 0;
|
||||
signatureCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
signatureCanvas.setAttribute('data-x', x);
|
||||
signatureCanvas.setAttribute('data-y', y);
|
||||
}, 0);
|
||||
};
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let usingSignaturePad = false;
|
||||
|
||||
toggleDrawSignatureBtn.addEventListener('click', () => {
|
||||
usingSignaturePad = !usingSignaturePad;
|
||||
if (usingSignaturePad) {
|
||||
signatureCanvas.width = 0;
|
||||
signatureCanvas.height = 0;
|
||||
}
|
||||
document.querySelector('.signature-pad-container').style.display = usingSignaturePad ? 'block' : 'none';
|
||||
toggleDrawSignatureBtn.textContent = usingSignaturePad
|
||||
? 'Import signature image'
|
||||
: 'Draw signature';
|
||||
});
|
||||
|
||||
|
||||
clearSignatureBtn.addEventListener('click', () => {
|
||||
signaturePad.clear();
|
||||
});
|
||||
|
||||
saveSignatureBtn.addEventListener('click', async () => {
|
||||
if (!signaturePad.isEmpty()) {
|
||||
const dataURL = signaturePad.toDataURL();
|
||||
$("input[name=signature-type]").change(function() {
|
||||
const drawSignatureInput = document.getElementById('draw-signature');
|
||||
signaturePadContainer.style.display = drawSignatureInput.checked ? 'block' : 'none';
|
||||
document.querySelector('input[name=signature-upload]').closest(".custom-file-chooser").style.display = drawSignatureInput.checked ? 'none' : 'block';
|
||||
|
||||
if (drawSignatureInput.checked) {
|
||||
populateSignatureFromPad();
|
||||
} else {
|
||||
populateSignatureFromFileUpload();
|
||||
}
|
||||
});
|
||||
|
||||
function populateSignature(imgUrl) {
|
||||
const img = new Image();
|
||||
img.src = dataURL;
|
||||
img.onload = () => {
|
||||
const ctx = signatureCanvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, signatureCanvas.width, signatureCanvas.height);
|
||||
|
@ -161,16 +145,46 @@
|
|||
signatureCanvas.height = img.height;
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height);
|
||||
signatureCanvas.hidden = false;
|
||||
setTimeout(() => {
|
||||
|
||||
const x = 0;
|
||||
const y = 0;
|
||||
signatureCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
signatureCanvas.setAttribute('data-x', x);
|
||||
signatureCanvas.setAttribute('data-y', y);
|
||||
}, 0);
|
||||
};
|
||||
|
||||
// calcualte the max size
|
||||
const containerWidth = parseInt(getComputedStyle(pdfCanvas).width.replace('px',''));
|
||||
const containerHeight = parseInt(getComputedStyle(pdfCanvas).height.replace('px',''));
|
||||
const containerAspectRatio = containerWidth / containerHeight;
|
||||
const imgAspectRatio = img.width / img.height;
|
||||
if (imgAspectRatio > containerAspectRatio) {
|
||||
const width = Math.min(img.width, containerWidth);
|
||||
signatureCanvas.style.width = width+'px';
|
||||
signatureCanvas.style.height = (width/imgAspectRatio)+'px';
|
||||
} else {
|
||||
const height = Math.min(img.height, containerHeight);
|
||||
signatureCanvas.style.width = (height*imgAspectRatio)+'px';
|
||||
signatureCanvas.style.height = height+'px';
|
||||
}
|
||||
});
|
||||
};
|
||||
img.src = imgUrl;
|
||||
}
|
||||
function populateSignatureFromFileUpload() {
|
||||
const file = signatureUpload.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => populateSignature(e.target.result);
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
function populateSignatureFromPad() {
|
||||
if (signaturePad.isEmpty()) return;
|
||||
|
||||
const dataURL = signaturePad.toDataURL();
|
||||
populateSignature(dataURL);
|
||||
}
|
||||
signatureUpload.addEventListener('change', populateSignatureFromFileUpload);
|
||||
saveSignatureBtn.addEventListener('click', populateSignatureFromPad);
|
||||
|
||||
|
||||
function renderPage(pageNum) {
|
||||
|
@ -270,13 +284,12 @@
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
async function dataURLToArrayBuffer(dataURL) {
|
||||
const response = await fetch(dataURL);
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue