qrcodedemo/examples/vanilla-js-example.html
Michael Mainguy 874f3c4412 Add standalone bundle for qrCodeUtils with all dependencies
- Created vite.standalone.config.js for optimized bundle building
- Added build scripts for standalone bundle generation
- Generated three formats: IIFE (28KB), UMD (28KB), ES Module (61KB)
- Includes all dependencies: qrcode and imagetracer
- Added comprehensive documentation and examples
- Created build script with detailed bundle information
- Added terser for minification optimization
- Fixed package.json dependencies and scripts
2025-08-01 17:17:36 -05:00

308 lines
11 KiB
HTML

<!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 - Vanilla JavaScript Example</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input, textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
}
textarea {
height: 100px;
resize: vertical;
}
button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
margin-right: 10px;
}
button:hover {
background-color: #0056b3;
}
.qr-display {
text-align: center;
margin-top: 30px;
}
.qr-display img {
max-width: 100%;
border: 1px solid #ddd;
border-radius: 5px;
}
.color-controls {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.color-input {
flex: 1;
}
.color-input input {
width: 100%;
height: 40px;
padding: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>QR Code Generator - Vanilla JavaScript</h1>
<div class="form-group">
<label for="text-input">Enter text to generate QR code:</label>
<textarea id="text-input" placeholder="Enter your text here..."></textarea>
</div>
<div class="color-controls">
<div class="color-input">
<label for="foreground-color">QR Code Color:</label>
<input type="color" id="foreground-color" value="#000000">
</div>
<div class="color-input">
<label for="background-color">Background Color:</label>
<input type="color" id="background-color" value="#FFFFFF">
</div>
</div>
<div class="form-group">
<label for="image-upload">Upload Custom Image (optional):</label>
<input type="file" id="image-upload" accept="image/*">
</div>
<div class="form-group">
<label for="image-size">Image Size (%):</label>
<input type="range" id="image-size" min="5" max="30" value="20">
<span id="image-size-value">20%</span>
</div>
<div class="form-group">
<button onclick="generateQRCode()">Generate QR Code</button>
<button onclick="exportAsSVG()">Export as SVG</button>
<button onclick="clearAll()">Clear</button>
</div>
<div class="qr-display" id="qr-display"></div>
</div>
<!-- Import the utility functions -->
<script type="module">
import {
generateQRCode,
generateCompleteSVGQRCode,
downloadSVG,
fileToDataURL,
validateImageFile
} from '../src/utils/qrCodeUtils.js';
// Make functions available globally
window.generateQRCode = generateQRCode;
window.generateCompleteSVGQRCode = generateCompleteSVGQRCode;
window.downloadSVG = downloadSVG;
window.fileToDataURL = fileToDataURL;
window.validateImageFile = validateImageFile;
// Global variables
let customImageUrl = null;
// Initialize
document.addEventListener('DOMContentLoaded', function() {
// Update image size display
const sizeSlider = document.getElementById('image-size');
const sizeValue = document.getElementById('image-size-value');
sizeSlider.addEventListener('input', function() {
sizeValue.textContent = this.value + '%';
});
// Handle image upload
const imageUpload = document.getElementById('image-upload');
imageUpload.addEventListener('change', async function(event) {
const file = event.target.files[0];
if (file) {
const validation = validateImageFile(file);
if (!validation.success) {
alert(validation.error);
return;
}
try {
customImageUrl = await fileToDataURL(file);
console.log('Image uploaded successfully');
} catch (error) {
console.error('Error processing image file:', error);
alert('Error processing image file');
}
}
});
});
// Generate QR Code function
window.generateQRCode = async function() {
const text = document.getElementById('text-input').value.trim();
const foregroundColor = document.getElementById('foreground-color').value;
const backgroundColor = document.getElementById('background-color').value;
const imageSize = parseInt(document.getElementById('image-size').value);
if (!text) {
alert('Please enter some text to generate a QR code');
return;
}
try {
const qrDisplay = document.getElementById('qr-display');
qrDisplay.innerHTML = '<p>Generating QR code...</p>';
// Generate QR code with custom image if provided
const qrCodeUrl = await generateQRCode(text, foregroundColor, backgroundColor);
if (customImageUrl) {
// Add custom image to QR code
const qrWithImage = await addImageToQRCode(qrCodeUrl, customImageUrl, imageSize);
displayQRCode(qrWithImage);
} else {
displayQRCode(qrCodeUrl);
}
} catch (error) {
console.error('Error generating QR code:', error);
alert('Error generating QR code');
}
};
// Export as SVG function
window.exportAsSVG = async function() {
const text = document.getElementById('text-input').value.trim();
const foregroundColor = document.getElementById('foreground-color').value;
const backgroundColor = document.getElementById('background-color').value;
const imageSize = parseInt(document.getElementById('image-size').value);
if (!text) {
alert('Please enter some text to generate a QR code');
return;
}
try {
// Generate complete SVG QR code
const svgContent = await generateCompleteSVGQRCode(
text,
customImageUrl,
imageSize,
foregroundColor,
backgroundColor
);
if (svgContent) {
downloadSVG(svgContent, 'qrcode.svg');
} else {
alert('Error generating SVG');
}
} catch (error) {
console.error('Error exporting SVG:', error);
alert('Error exporting SVG');
}
};
// Clear all function
window.clearAll = function() {
document.getElementById('text-input').value = '';
document.getElementById('image-upload').value = '';
document.getElementById('qr-display').innerHTML = '';
customImageUrl = null;
};
// Display QR code function
function displayQRCode(dataUrl) {
const qrDisplay = document.getElementById('qr-display');
qrDisplay.innerHTML = `
<h3>Generated QR Code:</h3>
<img src="${dataUrl}" alt="QR Code" style="max-width: 300px;">
`;
}
// Add image to QR code function (simplified version)
async function addImageToQRCode(qrCodeUrl, imageUrl, imageSize) {
return new Promise((resolve) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 512;
canvas.height = 512;
const qrImage = new Image();
const customImage = new Image();
qrImage.onload = () => {
ctx.drawImage(qrImage, 0, 0, 512, 512);
customImage.onload = () => {
const calculatedImageSize = 512 * (imageSize / 100);
const margin = 16;
const boxSize = calculatedImageSize + (margin * 2);
const boxX = (512 - boxSize) / 2;
const boxY = (512 - boxSize) / 2;
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(boxX, boxY, boxSize, boxSize);
const imageX = boxX + margin;
const imageY = boxY + margin;
ctx.drawImage(customImage, imageX, imageY, calculatedImageSize, calculatedImageSize);
resolve(canvas.toDataURL('image/png'));
};
customImage.onerror = () => {
console.error('Error loading custom image');
resolve(qrCodeUrl);
};
customImage.src = imageUrl;
};
qrImage.onerror = () => {
console.error('Error loading QR code');
resolve('');
};
qrImage.src = qrCodeUrl;
});
}
</script>
</body>
</html>