From b99e18a0be7f253aadcfc4703130eb88582684dc Mon Sep 17 00:00:00 2001 From: AtharvaPatil86 Date: Sat, 25 Oct 2025 17:38:45 +0530 Subject: [PATCH] Added Qr Code generator and download qr feature --- projects/qr-code-generator-scanner/index.html | 44 ++++-- projects/qr-code-generator-scanner/main.js | 126 ++++++++++++++++-- projects/qr-code-generator-scanner/styles.css | 118 +++++++++++++++- 3 files changed, 268 insertions(+), 20 deletions(-) diff --git a/projects/qr-code-generator-scanner/index.html b/projects/qr-code-generator-scanner/index.html index da91799..5cd97e6 100644 --- a/projects/qr-code-generator-scanner/index.html +++ b/projects/qr-code-generator-scanner/index.html @@ -1,20 +1,46 @@ - - + + QR Code Generator & Scanner - + + + + + + + +

QR Code Generator & Scanner

+
- - - - - + +
+

Generate a QR Code

+ + + +
+ + +
+ + +
+

Scan a QR Code

+
+

+
+ - \ No newline at end of file + diff --git a/projects/qr-code-generator-scanner/main.js b/projects/qr-code-generator-scanner/main.js index 5e1eae6..d8f3b9c 100644 --- a/projects/qr-code-generator-scanner/main.js +++ b/projects/qr-code-generator-scanner/main.js @@ -1,14 +1,120 @@ -// TODO: Generate QR code from input text/URL -// TODO: Display generated QR code -// TODO: Download QR code image -// TODO: Scan uploaded QR code image -// TODO: Display scanned QR code result function initQRCodeGeneratorScanner() { - // TODO: Generate QR code from input - // TODO: Scan QR code from image - // TODO: Display results - // TODO: Download QR code + const qrContainer = document.getElementById("qr-container"); + + + qrContainer.innerHTML = ` +
+

Generate a QR Code

+ + +
+ +
+ +
+

Scan a QR Code (Upload Image)

+ +

+
+ `; + + const qrInput = document.getElementById("qr-input"); + const generateBtn = document.getElementById("generate-btn"); + const qrContainerEl = document.getElementById("qrcode"); + const downloadBtn = document.getElementById("download-btn"); + const fileInput = document.getElementById("file-input"); + const resultEl = document.getElementById("scan-result"); + + let qrCodeInstance = null; + + generateBtn.addEventListener("click", () => { + const text = qrInput.value.trim(); + if (!text) { + alert("Please enter some text or a URL!"); + return; + } + + qrContainerEl.innerHTML = ""; + + qrCodeInstance = new QRCode(qrContainerEl, { + text, + width: 200, + height: 200, + }); + + downloadBtn.classList.remove("hidden"); + }); + + downloadBtn.addEventListener("click", () => { + const img = qrContainerEl.querySelector("img"); + if (!img) { + alert("Please generate a QR code first!"); + return; + } + + const link = document.createElement("a"); + link.href = img.src; + link.download = "qrcode.png"; + link.click(); + }); + + + fileInput.addEventListener("change", async (e) => { + const file = e.target.files[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = async function () { + const imageDataUrl = reader.result; + resultEl.textContent = "Scanning..."; + + try { + const result = await scanQRCodeFromImage(imageDataUrl); + if (result) { + resultEl.textContent = `Scanned Result: ${result}`; + } else { + resultEl.textContent = "No QR code detected."; + } + } catch (err) { + console.error(err); + resultEl.textContent = "Error scanning QR code."; + } + }; + reader.readAsDataURL(file); + }); +} + +async function scanQRCodeFromImage(imageDataUrl) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + canvas.width = img.width; + canvas.height = img.height; + ctx.drawImage(img, 0, 0, img.width, img.height); + + const imageData = ctx.getImageData(0, 0, img.width, img.height); + + + if (typeof jsQR === "undefined") { + const script = document.createElement("script"); + script.src = "https://cdn.jsdelivr.net/npm/jsqr/dist/jsQR.js"; + script.onload = () => { + const code = jsQR(imageData.data, imageData.width, imageData.height); + resolve(code ? code.data : null); + }; + script.onerror = () => reject("Failed to load jsQR library."); + document.body.appendChild(script); + } else { + const code = jsQR(imageData.data, imageData.width, imageData.height); + resolve(code ? code.data : null); + } + }; + img.onerror = reject; + img.src = imageDataUrl; + }); } -window.addEventListener('DOMContentLoaded', initQRCodeGeneratorScanner); \ No newline at end of file +window.addEventListener("DOMContentLoaded", initQRCodeGeneratorScanner); diff --git a/projects/qr-code-generator-scanner/styles.css b/projects/qr-code-generator-scanner/styles.css index 8cd3811..c480cab 100644 --- a/projects/qr-code-generator-scanner/styles.css +++ b/projects/qr-code-generator-scanner/styles.css @@ -1 +1,117 @@ -/* TODO: Style QR container, input, QR code display, download button, scan input, result display */ \ No newline at end of file + + +body { + font-family: system-ui, sans-serif; + text-align: center; + padding: 2rem 1rem; + background-color: var(--bg, #fafafa); + color: var(--text, #222); +} + +h1 { + font-size: 1.8rem; + margin-bottom: 1.5rem; +} + +section { + margin: 2rem auto; + max-width: 400px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 1.5rem; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); +} + +h2 { + font-size: 1.2rem; + margin-bottom: 1rem; +} + +input[type="text"], +input[type="file"] { + width: 100%; + padding: 0.6rem; + font-size: 1rem; + border: 1px solid #ccc; + border-radius: 4px; + margin-bottom: 0.75rem; + box-sizing: border-box; +} + +button { + background-color: #007bff; + color: white; + border: none; + border-radius: 4px; + padding: 0.6rem 1.2rem; + font-size: 1rem; + cursor: pointer; + transition: background-color 0.2s ease; +} + +button:hover { + background-color: #005fcc; +} + +button.hidden { + display: none; +} + +#qrcode { + margin: 1rem auto; +} + +#scan-result { + margin-top: 0.75rem; + font-weight: 500; + color: #333; + word-break: break-word; +} + +#file-input { + margin-top: 0.5rem; +} + +#qr-container { + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; +} + +body.dark-mode { + background-color: #121212; + color: #e0e0e0; +} + +body.dark-mode section { + background-color: #1e1e1e; + border-color: #333; +} + +body.dark-mode input, +body.dark-mode button { + background-color: #2a2a2a; + color: #eee; + border-color: #444; +} + +body.dark-mode button { + background-color: #4e8cff; +} + +body.dark-mode button:hover { + background-color: #3c6fd1; +} + +@media (max-width: 600px) { + body { + padding: 1rem; + } + + section { + width: 100%; + padding: 1rem; + } +}