Redesigned the rotate page
This commit is contained in:
parent
fe3088acfc
commit
58423bfc21
2 changed files with 108 additions and 18 deletions
|
@ -6,6 +6,9 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.3.122/build/pdf.min.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.3.122/web/pdf_viewer.min.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" th:href="@{dark-mode.css}" id="dark-mode-styles">
|
||||
<script>
|
||||
function toggleDarkMode() {
|
||||
|
@ -94,3 +97,24 @@
|
|||
}
|
||||
</script>
|
||||
</th:block>
|
||||
|
||||
<th:block th:fragment="fileSelector(name, multiple)">
|
||||
<div class="custom-file-chooser">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" th:name="${name}" th:id="${name}+'-input'" th:multiple="${multiple}">
|
||||
<label class="custom-file-label" th:for="${name}+'-input'">Choose file</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$([[${"#"+name+"-input"}]]).on("change", function() {
|
||||
const files = $(this).get(0).files;
|
||||
const fileNames = Array.from(files).map(f => f.name).join(", ");
|
||||
if (fileNames) {
|
||||
$(this).siblings(".custom-file-label").addClass("selected").html(fileNames);
|
||||
} else {
|
||||
$(this).siblings(".custom-file-label").addClass("selected").html("Choose file");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
|
@ -15,28 +15,20 @@
|
|||
<div class="col-md-6">
|
||||
<h2>Rotate PDF</h2>
|
||||
|
||||
<form action="#" th:action="@{rotate-pdf}" th:object="${rotateForm}" method="post" enctype="multipart/form-data">
|
||||
<div th:replace="fragments/common :: fileSelector(name='fileInput', multiple=false)"></div>
|
||||
<input type="hidden" id="angleInput" name="angle" value="0">
|
||||
|
||||
|
||||
<form action="#" th:action="@{rotate-pdf}" th:object="${rotateForm}"
|
||||
method="post" enctype="multipart/form-data">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="fileInput"
|
||||
name="fileInput" required> <label
|
||||
class="custom-file-label" for="fileInput">Choose PDF</label>
|
||||
<div class="previewContainer">
|
||||
<img id="pdf-preview"/>
|
||||
</div>
|
||||
|
||||
<label for="angle">Select rotation angle (in multiples of
|
||||
90 degrees):</label> <select id="angle" class="form-control" name="angle">
|
||||
<option value="90">90</option>
|
||||
<option value="180">180</option>
|
||||
<option value="270">270</option>
|
||||
<option value="-90">-90</option>
|
||||
<option value="-180">-180</option>
|
||||
<option value="-270">-270</option>
|
||||
</select> <br>
|
||||
<button type="submit" class="btn btn-primary">Rotate</button>
|
||||
<div class="buttonContainer">
|
||||
<button type="button" class="btn btn-secondary" onclick="rotate(-90)">L</button>
|
||||
<button type="submit" class="btn btn-primary">Complete</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="rotate(90)">R</button>
|
||||
</div>
|
||||
</form>
|
||||
<th:block th:insert="~{fragments/common :: filelist}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,6 +36,80 @@
|
|||
</div>
|
||||
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const angleInput = document.getElementById("angleInput");
|
||||
const fileInput = document.getElementById("fileInput-input");
|
||||
const preview = document.getElementById("pdf-preview");
|
||||
fileInput.addEventListener("change", async function() {
|
||||
console.log("loading pdf");
|
||||
|
||||
preview.parentElement.style.display = "block";
|
||||
document.querySelector(".buttonContainer").style.display = "flex";
|
||||
|
||||
var file = fileInput.files[0];
|
||||
var url = URL.createObjectURL(file)
|
||||
var loadingTask = pdfjsLib.getDocument(url);
|
||||
|
||||
const pdf = await loadingTask.promise;
|
||||
const page = await pdf.getPage(1);
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
canvas.width = page.view[2];
|
||||
canvas.height = page.view[3];
|
||||
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: canvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 })
|
||||
};
|
||||
|
||||
await page.render(renderContext).promise;
|
||||
preview.src = canvas.toDataURL();
|
||||
});
|
||||
|
||||
function rotate(deg) {
|
||||
var lastTransform = preview.style.transform;
|
||||
if (!lastTransform) {
|
||||
lastTransform = "0";
|
||||
}
|
||||
const lastAngle = parseInt(lastTransform.replace(/[^\d-]/g, ''));
|
||||
const newAngle = lastAngle + deg;
|
||||
|
||||
preview.style.transform = "rotate(" + newAngle + "deg)";
|
||||
angleInput.value = newAngle;
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#pdf-preview {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
box-shadow: 0 0 4px rgba(100,100,100,.25);
|
||||
transition: transform .3s;
|
||||
}
|
||||
.previewContainer {
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
border: 1px solid rgba(0,0,0,.125);
|
||||
border-radius: 0.25rem;
|
||||
margin: 1rem 0 0;
|
||||
padding: 15px;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: none;
|
||||
justify-content: space-around;
|
||||
}
|
||||
button {
|
||||
top-margin: -100%;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue