Last active
May 9, 2025 05:17
-
-
Save fedir/1d4271814e33fb8fdba2e4bf7fc81168 to your computer and use it in GitHub Desktop.
Simple one-page HTML/JS QR Code Generator using qrcodejs // Demo: https://www.fedir.fr/tools/qrcode.html // Made with Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>QR Code Generator</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
background-color: #f7f7f7; | |
} | |
h1 { | |
color: #333; | |
text-align: center; | |
} | |
.container { | |
background-color: white; | |
padding: 20px; | |
border-radius: 8px; | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
} | |
.form-group { | |
margin-bottom: 20px; | |
} | |
textarea { | |
width: 100%; | |
padding: 10px; | |
border: 1px solid #ddd; | |
border-radius: 4px; | |
min-height: 100px; | |
margin-bottom: 10px; | |
font-family: inherit; | |
box-sizing: border-box; | |
} | |
button { | |
background-color: #4CAF50; | |
color: white; | |
border: none; | |
padding: 10px 15px; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 16px; | |
} | |
button:hover { | |
background-color: #45a049; | |
} | |
.result { | |
margin-top: 20px; | |
text-align: center; | |
display: none; | |
max-width: 100%; | |
} | |
.qr-code { | |
margin: 20px auto; | |
text-align: center; | |
max-width: 100%; | |
overflow: hidden; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
.qr-code canvas, .qr-code img { | |
max-width: 100%; | |
height: auto; | |
display: block; | |
margin: 0 auto; | |
} | |
.error { | |
color: red; | |
margin-top: 10px; | |
display: none; | |
} | |
.download-btn { | |
margin-top: 15px; | |
background-color: #2196F3; | |
display: none; /* Hidden */ | |
} | |
.controls { | |
display: flex; | |
flex-direction: column; | |
gap: 15px; | |
margin-top: 15px; | |
} | |
.size-control { | |
display: flex; | |
align-items: center; | |
} | |
.size-control label { | |
margin-right: 10px; | |
} | |
/* Responsive adjustments */ | |
@media (min-width: 480px) { | |
.controls { | |
flex-direction: row; | |
justify-content: space-between; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>QR Code Generator</h1> | |
<div class="form-group"> | |
<label for="text"><strong>Enter text for QR code:</strong></label> | |
<textarea id="text" placeholder="Enter URL, text, or contact information here..."></textarea> | |
<div class="controls"> | |
<div class="size-control"> | |
<label for="size">Size:</label> | |
<select id="size"> | |
<option value="128">Small (128×128)</option> | |
<option value="256" selected>Medium (256×256)</option> | |
<option value="512">Large (512×512)</option> | |
<option value="800">Extra Large (800×800)</option> | |
</select> | |
</div> | |
<div> | |
<button id="generate-btn" onclick="generateQRCode()">Generate QR Code</button> | |
</div> | |
</div> | |
</div> | |
<div id="error-message" class="error"></div> | |
<div id="result" class="result"> | |
<h2>Your QR Code:</h2> | |
<div id="qrcode" class="qr-code"></div> | |
<p>Scan this QR code with a QR code reader to access the content.</p> | |
</div> | |
</div> | |
<!-- qrcodejs library --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script> | |
<script> | |
// QR code object | |
let qrcode = null; | |
// Function to validate input | |
function validateInput(text) { | |
if (!text || text.trim() === '') { | |
return "Please enter some text to generate a QR code."; | |
} | |
if (text.length > 1000) { | |
return "Text is too long. Please limit to 1000 characters."; | |
} | |
return ""; | |
} | |
// Function to generate QR code | |
function generateQRCode() { | |
// Get the input text and size | |
const textInput = document.getElementById('text').value; | |
const size = parseInt(document.getElementById('size').value); | |
const errorElement = document.getElementById('error-message'); | |
const resultElement = document.getElementById('result'); | |
// Validate input | |
const error = validateInput(textInput); | |
if (error) { | |
errorElement.textContent = error; | |
errorElement.style.display = 'block'; | |
resultElement.style.display = 'none'; | |
return; | |
} | |
// Clear any previous errors | |
errorElement.style.display = 'none'; | |
// Clear previous QR code | |
const qrcodeElement = document.getElementById('qrcode'); | |
qrcodeElement.innerHTML = ''; | |
// Calculate appropriate size based on container width | |
const containerWidth = document.querySelector('.container').offsetWidth - 40; // Subtract padding | |
const actualSize = Math.min(size, containerWidth); | |
// Generate new QR code | |
qrcode = new QRCode(qrcodeElement, { | |
text: textInput, | |
width: actualSize, | |
height: actualSize, | |
colorDark: "#000000", | |
colorLight: "#ffffff", | |
correctLevel: QRCode.CorrectLevel.H | |
}); | |
// Center the QR code if it's smaller than the container | |
if (actualSize < containerWidth) { | |
// Add additional styling to ensure proper centering | |
setTimeout(() => { | |
const qrCanvas = qrcodeElement.querySelector('canvas'); | |
const qrImg = qrcodeElement.querySelector('img'); | |
if (qrCanvas) { | |
qrCanvas.style.margin = '0 auto'; | |
} | |
if (qrImg) { | |
qrImg.style.margin = '0 auto'; | |
} | |
}, 100); // Small delay to ensure elements are rendered | |
} | |
// Show the result | |
resultElement.style.display = 'block'; | |
} | |
// Function to download QR code as image | |
function downloadQRCode() { | |
if (!qrcode) return; | |
// Get the canvas element | |
const canvas = document.querySelector('#qrcode canvas'); | |
if (!canvas) return; | |
// Get the selected size | |
const selectedSize = parseInt(document.getElementById('size').value); | |
// If we want to download at the original (full) size, we need to recreate the QR code | |
// at the original size on a temporary canvas | |
const tempCanvas = document.createElement('canvas'); | |
tempCanvas.width = selectedSize; | |
tempCanvas.height = selectedSize; | |
const ctx = tempCanvas.getContext('2d'); | |
// Fill with white background | |
ctx.fillStyle = '#ffffff'; | |
ctx.fillRect(0, 0, selectedSize, selectedSize); | |
// Draw the QR code at full size | |
// Get the QR code image | |
const img = document.querySelector('#qrcode img'); | |
if (img) { | |
// Create a new QRCode instance at full size | |
const tempDiv = document.createElement('div'); | |
tempDiv.style.display = 'none'; | |
document.body.appendChild(tempDiv); | |
const tempQR = new QRCode(tempDiv, { | |
text: document.getElementById('text').value, | |
width: selectedSize, | |
height: selectedSize, | |
colorDark: "#000000", | |
colorLight: "#ffffff", | |
correctLevel: QRCode.CorrectLevel.H | |
}); | |
// Get the canvas from the temporary QR code | |
const fullSizeCanvas = tempDiv.querySelector('canvas'); | |
if (fullSizeCanvas) { | |
// Use the full-size canvas for the download | |
const dataURL = fullSizeCanvas.toDataURL('image/png'); | |
// Create download link | |
const link = document.createElement('a'); | |
link.download = 'qrcode.png'; | |
link.href = dataURL; | |
// Trigger download | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
} | |
// Clean up | |
document.body.removeChild(tempDiv); | |
} else { | |
// Fallback to the displayed canvas if there's an issue | |
const dataURL = canvas.toDataURL('image/png'); | |
// Create download link | |
const link = document.createElement('a'); | |
link.download = 'qrcode.png'; | |
link.href = dataURL; | |
// Trigger download | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
} | |
} | |
// Add event listener for Enter key | |
document.getElementById('text').addEventListener('keypress', function(event) { | |
if (event.key === 'Enter' && !event.shiftKey) { | |
event.preventDefault(); | |
generateQRCode(); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment