diff --git a/pr-preview/pr-14/assets/arrow-down 1.svg b/pr-preview/pr-14/assets/arrow-down.svg similarity index 100% rename from pr-preview/pr-14/assets/arrow-down 1.svg rename to pr-preview/pr-14/assets/arrow-down.svg diff --git a/pr-preview/pr-14/assets/arrow-up 1.svg b/pr-preview/pr-14/assets/arrow-up.svg similarity index 100% rename from pr-preview/pr-14/assets/arrow-up 1.svg rename to pr-preview/pr-14/assets/arrow-up.svg diff --git a/pr-preview/pr-14/assets/external-link.svg b/pr-preview/pr-14/assets/external-link.svg new file mode 100644 index 0000000..55c5f58 --- /dev/null +++ b/pr-preview/pr-14/assets/external-link.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/pr-preview/pr-14/assets/photo-camera.svg b/pr-preview/pr-14/assets/photo-camera.svg new file mode 100644 index 0000000..f603bed --- /dev/null +++ b/pr-preview/pr-14/assets/photo-camera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-14/assets/upload-image.svg b/pr-preview/pr-14/assets/upload-menu.svg similarity index 100% rename from pr-preview/pr-14/assets/upload-image.svg rename to pr-preview/pr-14/assets/upload-menu.svg diff --git a/pr-preview/pr-14/assets/upload.svg b/pr-preview/pr-14/assets/upload.svg new file mode 100644 index 0000000..7a89991 --- /dev/null +++ b/pr-preview/pr-14/assets/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-14/assets/video-camera.svg b/pr-preview/pr-14/assets/video-camera.svg new file mode 100644 index 0000000..d68e94c --- /dev/null +++ b/pr-preview/pr-14/assets/video-camera.svg @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/pr-preview/pr-14/css/index.css b/pr-preview/pr-14/css/index.css index a4205e2..724a327 100644 --- a/pr-preview/pr-14/css/index.css +++ b/pr-preview/pr-14/css/index.css @@ -238,7 +238,7 @@ img { display: none; } -.scanner-container .header .upload-image-btn { +.scanner-container .header .upload-menu-btn { width: 30px; height: 30px; cursor: pointer; @@ -247,15 +247,59 @@ img { cursor: pointer; } -.scanner-container .header .upload-image-icon { +.scanner-container .header .upload-menu-icon { width: 24px; height: 24px; } -.scanner-container .header .upload-image-icon:hover { +.scanner-container .header .upload-menu-list { + position: absolute; + top: 54px; /* Header height 46px + triangle 8px*/ + left: 70px; + background-color: #000000; + z-index: 3; + display: none; + border-right: #aaaaaa; +} + +/* Tooltip Triangle */ +.scanner-container .header .upload-menu-list::after { + content: ""; + position: absolute; + top: -16px; /* At the top of the information list */ + left: 1rem; /* 1rem margin */ + /* margin-left: -5px; */ + border-width: 8px; + border-style: solid; + border-color: transparent transparent #2b2b2b transparent; /* triangle */ +} + +.scanner-container .header .upload-menu-list .menu-item { + width: 100%; + border-bottom: 1px solid rgb(55, 55, 55); + padding: 10px; + cursor: pointer; + background-color: #2b2b2b; + display: flex; + align-items: center; + justify-content: space-between; + gap: 5px; + overflow: hidden; + user-select: none; + color: #aaaaaa; + font-size: 12px; + font-family: OpenSans-Regular; + text-decoration: none; +} + +.scanner-container .header .upload-menu-list .menu-item:hover { opacity: 0.8; } +.scanner-container .header .upload-menu-list .menu-item:last-child { + border: unset; +} + .result-container { position: absolute; width: 100%; diff --git a/pr-preview/pr-14/index.html b/pr-preview/pr-14/index.html index 81638c7..7185249 100644 --- a/pr-preview/pr-14/index.html +++ b/pr-preview/pr-14/index.html @@ -47,45 +47,24 @@

Quick Start Options

- - - - - - - - - - - down - up + camera + down + up
- -
- upload-image +
+ upload-menu +
+
+ + +
music @@ -117,43 +96,11 @@

Quick Start Options

target="_blank" > About - - - - - - + link-icon Github Projects - - - - - - + link-icon Quick Start Options target="_blank" > Contact Us - - - - - - + link-icon
diff --git a/pr-preview/pr-14/js/const.js b/pr-preview/pr-14/js/const.js index bf96991..4af569f 100644 --- a/pr-preview/pr-14/js/const.js +++ b/pr-preview/pr-14/js/const.js @@ -28,11 +28,15 @@ const homePage = document.querySelector(".home-page"); const cameraViewContainer = document.querySelector(".camera-view-container"); -const uploadImageInput = document.querySelector(".upload-image-input"); - const cameraListContainer = document.querySelector(".camera-list"); const cameraSelector = document.querySelector(".camera-selector"); +const uploadMenuBtn = document.querySelector(".upload-menu-btn"); +const uploadMenuList = document.querySelector(".upload-menu-list"); +const uploadImageBtn = document.querySelector(".upload-image-btn"); +const uploadImageInput = document.querySelector(".upload-image-input"); +const takePhotoBtn = document.querySelector(".take-photo-btn"); + const informationBtn = document.querySelectorAll(".information-btn"); const informationListContainer = document.querySelector(".information-list"); diff --git a/pr-preview/pr-14/js/index.js b/pr-preview/pr-14/js/index.js index ad166f0..7d7a828 100644 --- a/pr-preview/pr-14/js/index.js +++ b/pr-preview/pr-14/js/index.js @@ -115,10 +115,11 @@ const region = () => { // -----------Logic for calculating scan region ↑------------ window.addEventListener("click", () => { - cameraListContainer.style.display = "none"; + cameraListContainer.style.display = "none"; // hide camera list and reset arrow indicator up.style.display = "none"; down.style.display = "inline-block"; - informationListContainer.style.display = "none"; + informationListContainer.style.display = "none"; // hide information menu + uploadMenuList.style.display = "none"; // hide upload image menu }); // Recalculate the scan region when the window size changes @@ -162,8 +163,30 @@ uploadImageInput.addEventListener("change", async (event) => { console.error(errMsg); } }); +takePhotoBtn.addEventListener("click", async (event) => { + try { + const image = cameraEnhancer.fetchImage(); + const imageCvs = image.toCanvas(); + + // Open the camera after the model and .wasm files have loaded + pInit = pInit || (await init); + await pDataLoad.promise; + + // Decode selected image with 'both' template. + const result = await cvRouter.capture(imageCvs, SCAN_TEMPLATES.both); + console.log(result); + handleCapturedResult(result, image); + } catch (ex) { + let errMsg = ex.message || ex; + alert(errMsg); + console.error(errMsg); + } +}); cameraSelector.addEventListener("click", (e) => { + informationListContainer.style.display = "none"; // hide information menu + uploadMenuList.style.display = "none"; // hide upload image menu + e.stopPropagation(); const isShow = cameraListContainer.style.display === "block"; cameraListContainer.style.display = isShow ? "none" : "block"; @@ -187,8 +210,20 @@ closeSoundBtn.addEventListener("click", () => { informationBtn.forEach((infoBtn) => infoBtn.addEventListener("click", (e) => { + uploadMenuList.style.display = "none"; // hide upload image menu + cameraListContainer.style.display = "none"; // hide camera list + e.stopPropagation(); const isShow = informationListContainer.style.display === "block"; informationListContainer.style.display = isShow ? "none" : "block"; }) ); + +uploadMenuBtn.addEventListener("click", (e) => { + informationListContainer.style.display = "none"; // hide information menu + cameraListContainer.style.display = "none"; // hide camera list + + e.stopPropagation(); + const isShow = uploadMenuList.style.display === "block"; + uploadMenuList.style.display = isShow ? "none" : "block"; +}); diff --git a/pr-preview/pr-14/js/init.js b/pr-preview/pr-14/js/init.js index 849be92..f56840b 100644 --- a/pr-preview/pr-14/js/init.js +++ b/pr-preview/pr-14/js/init.js @@ -119,49 +119,69 @@ export const handleCapturedResult = (result, uploadedImage = null) => { mrzElement.classList.add("code"); parsedResultArea.appendChild(mrzElement); - // If a parsed result is obtained, use it to render the result page - if (parsedResults) { - const parseResultInfo = extractDocumentFields(parsedResults[0]); - Object.entries(parseResultInfo).map(([field, value]) => { - const resultElement = resultToHTMLElement(field, value); - parsedResultArea.appendChild(resultElement); - }); + const parseSuccess = displayResults(recognizedResults[0]?.text, parsedResults?.[0]); - if (uploadedImage && uploadedImage.type.startsWith("image/")) { - handleUploadedImage(uploadedImage); - } else if (originalImage) { - scannedImage.innerHTML = ""; - scannedImage.append(originalImage.toCanvas()); - } - } else { + if (!parseSuccess) { alert(`Failed to parse the content.`); parsedResultArea.style.justifyContent = "flex-start"; } - resultContainer.style.display = "flex"; - cameraListContainer.style.display = "none"; - informationListContainer.style.display = "none"; - scanModeContainer.style.display = "none"; - - cameraEnhancer.close(); - cvRouter.stopCapturing(); - cameraView.clearAllInnerDrawingItems(); + displayImage(uploadedImage || originalImage); + + dispose(); + } else if (uploadedImage) { + parsedResultArea.innerText = "No results found"; + displayImage(uploadedImage); + dispose(); + } +}; + +const displayResults = (recognizedText, parsedResult) => { + parsedResultArea.innerText = ""; + + // Display MRZ text + const mrzElement = resultToHTMLElement("MRZ String", recognizedText); + mrzElement.classList.add("code"); + parsedResultArea.appendChild(mrzElement); + + // Display parsed fields + if (parsedResult) { + const fields = extractDocumentFields(parsedResult); + Object.entries(fields).forEach(([field, value]) => { + parsedResultArea.appendChild(resultToHTMLElement(field, value)); + }); + return true; } + + return false; }; -function handleUploadedImage(file) { - const img = document.createElement("img"); - const imageUrl = URL.createObjectURL(file); +function displayImage(image) { + scannedImage.textContent = ""; + + if (image.type?.startsWith("image/")) { + const img = document.createElement("img"); + const imageUrl = URL.createObjectURL(image); + + img.src = imageUrl; + img.className = "uploaded-image"; + img.onload = () => URL.revokeObjectURL(imageUrl); - img.src = imageUrl; - img.className = "uploaded-image"; + scannedImage.append(img); + } else if (image.toCanvas) { + scannedImage.append(image.toCanvas()); + } +} - // Append the image to the div - scannedImage.innerHTMl = ""; - scannedImage.append(img); +function dispose() { + resultContainer.style.display = "flex"; // Show result container + cameraListContainer.style.display = "none"; // hide header menu windows + informationListContainer.style.display = "none"; + uploadMenuList.style.display = "none"; + scanModeContainer.style.display = "none"; // hide scan mode buttons - img.onload = () => { - URL.revokeObjectURL(imageUrl); - }; + cameraEnhancer.close(); + cvRouter.stopCapturing(); + cameraView.clearAllInnerDrawingItems(); } export { pDataLoad, init };