diff --git a/src/app/(category)/javascript/(projects)/Qr-code-reader/index.html b/src/app/(category)/javascript/(projects)/Qr-code-reader/index.html new file mode 100644 index 00000000..ddfefb1f --- /dev/null +++ b/src/app/(category)/javascript/(projects)/Qr-code-reader/index.html @@ -0,0 +1,20 @@ + + + + + + QR Code Scanner + + + +
+

QR Code Scanner

+
+
Result will appear here
+ +
+ + + + + diff --git a/src/app/(category)/javascript/(projects)/Qr-code-reader/script.js b/src/app/(category)/javascript/(projects)/Qr-code-reader/script.js new file mode 100644 index 00000000..d9a50586 --- /dev/null +++ b/src/app/(category)/javascript/(projects)/Qr-code-reader/script.js @@ -0,0 +1,32 @@ +let html5QrcodeScanner = null; + +function startScanner() { + if (html5QrcodeScanner === null) { + html5QrcodeScanner = new Html5QrcodeScanner( + "reader", + { + fps: 10, + qrbox: {width: 250, height: 250}, + aspectRatio: 1.0 + } + ); + + html5QrcodeScanner.render(onScanSuccess, onScanFailure); + } +} + +function onScanSuccess(decodedText, decodedResult) { + console.log(`Code matched = ${decodedText}`, decodedResult); + document.getElementById('result').innerHTML = + `

Decoded QR Code: ${decodedText}

`; + + // Optional: Add link if the QR code contains a URL + if (decodedText.startsWith('http')) { + document.getElementById('result').innerHTML += + `

Open Link

`; + } +} + +function onScanFailure(error) { + // console.warn(`Code scan error = ${error}`); +} \ No newline at end of file diff --git a/src/app/(category)/javascript/(projects)/Qr-code-reader/style.css b/src/app/(category)/javascript/(projects)/Qr-code-reader/style.css new file mode 100644 index 00000000..752fd460 --- /dev/null +++ b/src/app/(category)/javascript/(projects)/Qr-code-reader/style.css @@ -0,0 +1,216 @@ +/* Modern Variables */ +:root { + --primary-color: #6c63ff; + --secondary-color: #4CAF50; + --accent-color: #ff6b6b; + --background-color: #f8f9fa; + --card-background: #ffffff; + --text-color: #2d3436; + --shadow-color: rgba(108, 99, 255, 0.2); +} + +/* Reset and Base Styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + min-height: 100vh; + padding: 20px; + display: flex; + flex-direction: column; + align-items: center; + background: var(--background-color); + background-image: + radial-gradient(circle at 10% 20%, rgba(108, 99, 255, 0.1) 0%, transparent 50%), + radial-gradient(circle at 90% 80%, rgba(76, 175, 80, 0.1) 0%, transparent 50%); +} + +/* Container Styles */ +.container { + max-width: 800px; + width: 95%; + background: var(--card-background); + padding: 2rem; + border-radius: 20px; + box-shadow: 0 15px 30px var(--shadow-color); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.container::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 5px; + background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); +} + +/* Header Styles */ +h1 { + color: var(--primary-color); + text-align: center; + font-size: clamp(1.8rem, 4vw, 2.5rem); + margin-bottom: 2rem; + position: relative; + padding-bottom: 10px; +} + +h1::after { + content: ''; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60px; + height: 4px; + background: var(--primary-color); + border-radius: 2px; +} + +/* QR Reader Styles */ +#reader { + width: 100%; + margin: 2rem 0; + border-radius: 15px; + overflow: hidden; + box-shadow: 0 8px 20px rgba(0,0,0,0.1); +} + +#reader video { + border-radius: 15px; +} + +/* Result Display Styles */ +#result { + margin: 1.5rem 0; + padding: 1.5rem; + border: 2px solid var(--shadow-color); + border-radius: 12px; + background: rgba(108, 99, 255, 0.05); + transition: all 0.3s ease; + font-size: 1.1rem; + line-height: 1.6; +} + +#result:not(:empty) { + animation: fadeIn 0.5s ease; +} + +/* Button Styles */ +.button { + background: var(--primary-color); + color: white; + padding: 12px 30px; + border: none; + border-radius: 25px; + cursor: pointer; + font-size: 1.1rem; + font-weight: 600; + transition: all 0.3s ease; + display: block; + margin: 1.5rem auto; + box-shadow: 0 5px 15px var(--shadow-color); +} + +.button:hover { + background: var(--secondary-color); + transform: translateY(-2px); + box-shadow: 0 8px 20px var(--shadow-color); +} + +.button:active { + transform: translateY(0); +} + +/* Link Styles */ +a { + color: var(--primary-color); + text-decoration: none; + transition: color 0.3s ease; +} + +a:hover { + color: var(--secondary-color); + text-decoration: underline; +} + +/* Animations */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Responsive Design */ +@media (max-width: 768px) { + body { + padding: 15px; + } + + .container { + padding: 1.5rem; + width: 100%; + } + + #reader { + margin: 1rem 0; + } + + .button { + width: 100%; + padding: 15px; + } +} + +/* Loading State */ +.loading { + position: relative; + opacity: 0.7; +} + +.loading::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 30px; + height: 30px; + border: 3px solid var(--shadow-color); + border-top-color: var(--primary-color); + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* Success Message Styles */ +.success-message { + background: rgba(76, 175, 80, 0.1); + border-color: var(--secondary-color); + color: var(--secondary-color); + font-weight: 500; +} + +/* Error Message Styles */ +.error-message { + background: rgba(255, 107, 107, 0.1); + border-color: var(--accent-color); + color: var(--accent-color); + font-weight: 500; +} \ No newline at end of file