| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>Manga Image Translator</title> |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/picnic"> |
| <style type="text/css"> |
| #drop-area { border: 2px dashed #ccc; border-radius: 20px; width: 100%; margin: 50px auto; padding: 20px; } #drop-area.highlight { border-color: purple; } p { margin-top: 0; } .my-form { margin-bottom: 10px; } #gallery { text-align: center;} #gallery img { width: 95%; margin-bottom: 10px; vertical-align: middle; } .btn { display: inline-block; padding: 10px; background: #ccc; cursor: pointer; border-radius: 5px; border: 1px solid #ccc; } .btn:hover { background: #ddd; } #fileElem { display: none; } |
| .no-drag-select { |
| user-drag: none; |
| user-select: none; |
| } |
| </style> |
| </head> |
| <body> |
| <div> |
| <nav class="demo"> |
| <a href="#" class="brand">Manga Image Translator</a> |
|
|
| |
| <input id="bmenug" type="checkbox" class="show"> |
| <label for="bmenug" class="burger pseudo button">≡</label> |
|
|
| <div class="menu"> |
| <a href="https://github.com/zyddnys/manga-image-translator" target="_blank">About</a> |
| </div> |
| </nav> |
|
|
| <div class="flex one one-600 two-900" style="margin-top: 4em;"> |
| <div style="margin:50px auto"> |
| <div class="flex two" id="inputArea"> |
| <div id="s-area"><h2>Raw Text</h2></div> |
| <div id="t-area"><h2>Translation</h2></div> |
| </div> |
| <div> |
| <button type="button" id="submit-button" class="button" disabled="disabled" name="submit" onclick="submit()">Waiting for Image</button> |
| <button type="button" id="reset-button" class="button" disabled="disabled" name="reset" onclick="fullReset()">Reset</button> |
| </div> |
| </div> |
|
|
| <div> |
| <div id="drop-area"> |
| <form class="my-form" name="upload_images"> |
| <p>Upload image by dragging and dropping images onto the dashed region</p> |
| <input type="file" id="fileElem" accept="image/*" onchange="handleFiles(this.files)"> |
| <label class="btn" for="fileElem">Select some files</label> |
| </form> |
| <progress id="progress-bar" max=100 value=0 style="width:100%"></progress> |
| <div id="gallery"></div> |
| </div> |
| </div> |
|
|
| </div> |
| </div> |
|
|
|
|
|
|
| <script type="text/javascript"> |
| |
| var task_id = "" |
| var task_status = "" |
| |
| |
| |
| |
| let dropArea = document.getElementById("drop-area") |
| |
| |
| ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
| dropArea.addEventListener(eventName, preventDefaults, false) |
| document.body.addEventListener(eventName, preventDefaults, false) |
| }) |
| |
| |
| ;['dragenter', 'dragover'].forEach(eventName => { |
| dropArea.addEventListener(eventName, highlight, false) |
| }) |
| |
| ;['dragleave', 'drop'].forEach(eventName => { |
| dropArea.addEventListener(eventName, unhighlight, false) |
| }) |
| |
| |
| dropArea.addEventListener('drop', handleDrop, false) |
| |
| function preventDefaults (e) { |
| e.preventDefault() |
| e.stopPropagation() |
| } |
| |
| function highlight(e) { |
| dropArea.classList.add('highlight') |
| } |
| |
| function unhighlight(e) { |
| dropArea.classList.remove('active') |
| } |
| |
| function handleDrop(e) { |
| var dt = e.dataTransfer |
| var files = dt.files |
| |
| handleFiles(files) |
| } |
| |
| let uploadProgress = [] |
| let progressBar = document.getElementById('progress-bar') |
| |
| function initializeProgress(numFiles) { |
| progressBar.value = 0 |
| uploadProgress = [] |
| |
| for(let i = numFiles; i > 0; i--) { |
| uploadProgress.push(0) |
| } |
| } |
| |
| function updateProgress(fileNumber, percent) { |
| uploadProgress[fileNumber] = percent |
| let total = uploadProgress.reduce((tot, curr) => tot + curr, 0) / uploadProgress.length |
| progressBar.value = total |
| } |
| |
| function handleFiles(files) { |
| files = [...files] |
| initializeProgress(files.length) |
| files.forEach(uploadFile) |
| files.forEach(previewFile) |
| } |
| |
| function previewFile(file) { |
| let reader = new FileReader() |
| reader.readAsDataURL(file) |
| reader.onloadend = function() { |
| let img = document.createElement('img') |
| img.src = reader.result |
| img.classList.add('no-drag-select') |
| document.getElementById('gallery').appendChild(img) |
| } |
| } |
| |
| let submitButton = document.getElementById("submit-button") |
| let resetButton = document.getElementById("reset-button") |
| |
| function fullReset() { |
| var url = '/cancel-manual-request' |
| var xhr = new XMLHttpRequest() |
| xhr.open('POST', url, true) |
| xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8") |
| |
| xhr.addEventListener('readystatechange', function (e) { |
| if (xhr.readyState == 4 && xhr.status == 200) { |
| reset() |
| } |
| }) |
| xhr.send(JSON.stringify({ |
| "task_id": task_id, |
| })) |
| } |
| |
| function reset() { |
| var s_area = document.getElementById('s-area') |
| for (var i = s_area.children.length - 1; i >= 0; --i) { |
| var child = s_area.children[i] |
| if (child.tagName == "INPUT") { |
| child.remove() |
| } |
| } |
| var t_area = document.getElementById('t-area') |
| for (var i = t_area.children.length - 1; i >= 0; --i) { |
| var child = t_area.children[i] |
| if (child.tagName == "INPUT") { |
| child.remove() |
| } |
| } |
| |
| progressBar.value = 0 |
| submitButton.innerHTML = "Waiting for Image" |
| submitButton.onclick = null |
| submitButton.setAttribute("disabled", "disabled") |
| |
| resetButton.innerHTML = "No Image" |
| resetButton.onclick = fullReset |
| resetButton.setAttribute("disabled", "disabled") |
| |
| var img = document.getElementsByTagName("img")[0] |
| img.remove() |
| } |
| |
| function downloadImageAndReset(path) { |
| const url = "/result-type" |
| const xhr = new XMLHttpRequest() |
| xhr.open('GET', url, true) |
| xhr.addEventListener('readystatechange', function (e) { |
| if (xhr.readyState == 4 && xhr.status == 200) { |
| |
| |
| const a = document.createElement('a') |
| a.href = path |
| a.download = "result."+xhr.responseText |
| document.body.appendChild(a) |
| a.click() |
| document.body.removeChild(a) |
| |
| reset() |
| } |
| }) |
| xhr.send(null) |
| |
| } |
| |
| function uploadFile(file, i) { |
| |
| |
| submitButton.setAttribute("disabled", "disabled") |
| submitButton.innerHTML = "Uploading" |
| |
| resetButton.innerHTML = "Waiting" |
| resetButton.setAttribute("disabled", "disabled") |
| |
| |
| var url = '/manual-translate' |
| var xhr = new XMLHttpRequest() |
| var formData = new FormData() |
| xhr.open('POST', url, true) |
| xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') |
| |
| |
| xhr.upload.addEventListener("progress", function(e) { |
| updateProgress(i, (e.loaded * 100.0 / e.total) || 100) |
| if (e.loaded == e.total) |
| submitButton.innerHTML = "Processing" |
| }) |
| |
| xhr.addEventListener('readystatechange', function(e) { |
| if (xhr.readyState == 4 && xhr.status == 200) { |
| updateProgress(i, 100) |
| |
| const obj = JSON.parse(xhr.response) |
| console.log(obj) |
| |
| task_id = obj.task_id |
| task_status = obj.status |
| |
| var sArea = document.getElementById('s-area') |
| var tArea = document.getElementById('t-area') |
| |
| for (var i = 0; obj.trans_result != null && i < obj.trans_result.length; i++) { |
| var input_s = document.createElement("input") |
| var input_t = document.createElement("input") |
| |
| input_s.value = obj.trans_result[i].s |
| input_t.value = obj.trans_result[i].t |
| |
| sArea.appendChild(input_s) |
| tArea.appendChild(input_t) |
| |
| |
| } |
| |
| submitButton.removeAttribute("disabled") |
| submitButton.innerHTML = "Submit" |
| submitButton.onclick = submit |
| |
| resetButton.removeAttribute("disabled") |
| resetButton.innerHTML = "Reset" |
| } |
| else if (xhr.readyState == 4 && xhr.status != 200) { |
| |
| alert("upload failed for "+file.name) |
| } |
| }) |
| |
| |
| |
| formData.append('file', file) |
| xhr.send(formData) |
| } |
| |
| function submit() { |
| |
| submitButton.setAttribute("disabled", "disabled") |
| submitButton.innerHTML = "Running" |
| |
| resetButton.setAttribute("disabled", "disabled") |
| resetButton.innerHTML = "Waiting" |
| |
| var inputs = document.getElementsByTagName("input") |
| |
| var trans_result = [] |
| var j = ((inputs.length-2)/2)+1 |
| var k = 0 |
| |
| for (var i = 1; i<=((inputs.length-2)/2); i++) { |
| |
| trans_result[k] = { |
| 's' : inputs[i].value, |
| 't' : inputs[j].value |
| } |
| |
| j++ |
| k++ |
| } |
| |
| var postData = { |
| "task_id": task_id, |
| "status": task_status, |
| "trans_result": trans_result |
| } |
| |
| postData = JSON.stringify(postData) |
| |
| var url = '/post-manual-result' |
| var xhr = new XMLHttpRequest() |
| xhr.open('POST', url, true) |
| xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8") |
| |
| xhr.addEventListener('readystatechange', function(e) { |
| if (xhr.readyState == 4 && xhr.status == 200) { |
| var img = document.getElementsByTagName("img")[0] |
| img.src = "/result/" + task_id |
| img.onclick = (function (task_id) { |
| return function () { |
| downloadImageAndReset("/result/" + task_id) |
| }; |
| })(task_id) |
| } |
| else if (xhr.readyState == 4 && xhr.status != 200) { |
| |
| alert("Request failed!") |
| } |
| submitButton.removeAttribute("disabled") |
| submitButton.innerHTML = "Download Image" |
| submitButton.onclick = (function(task_id) { return function() { |
| downloadImageAndReset("/result/" + task_id) |
| };})(task_id) |
| |
| resetButton.removeAttribute("disabled") |
| resetButton.innerHTML = "Reset" |
| resetButton.onclick = reset |
| |
| }) |
| |
| |
| xhr.send(postData) |
| |
| |
| } |
| </script> |
| </body> |
| </html> |