Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
theg1239 committed Sep 15, 2024
0 parents commit df4a14f
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 0 deletions.
44 changes: 44 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!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>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="card">
<div class="input-section">
<h2>QR Code Generator</h2>
<textarea id="input-text" rows="5" placeholder="Enter links or text (one per line)..."></textarea>

<div class="options">
<div class="option-group">
<label for="custom-qr">Number of Random QRs</label>
<input type="number" id="custom-qr" placeholder="e.g. 5">
</div>

<div class="option-group">
<label for="logo-upload">Upload Custom Image (Optional)</label>
<input type="file" id="logo-upload" accept="image/*">
</div>
</div>

<button id="generate-btn" class="btn-primary">Generate</button>
</div>

<div class="output-section" id="output">
<h2>Generated QR Codes</h2>
<div class="qr-container"></div>
<button id="export-btn" class="btn-secondary" disabled>Export as ZIP</button>
</div>
</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcode-generator/1.4.4/qrcode.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script src="script.js"></script>
</body>
</html>
109 changes: 109 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
document.getElementById('generate-btn').addEventListener('click', function() {
const inputText = document.getElementById('input-text').value;
const customQrCount = parseInt(document.getElementById('custom-qr').value, 10);
const logoFile = document.getElementById('logo-upload').files[0];
const lines = inputText.split('\n').filter(line => line.trim() !== "");
const outputSection = document.querySelector('.qr-container');
const exportBtn = document.getElementById('export-btn');

outputSection.innerHTML = '';
exportBtn.disabled = true;
const qrCodes = [];

function generateRandomString() {
return Array(16).fill(0).map(() => Math.floor(Math.random() * 16).toString(16)).join('');
}

function drawLogoOnQr(qrCanvas, logoImage, callback) {
const ctx = qrCanvas.getContext('2d');
const logoSize = qrCanvas.width / 6;
ctx.drawImage(
logoImage,
(qrCanvas.width - logoSize) / 2,
(qrCanvas.height - logoSize) / 2,
logoSize,
logoSize
);
callback(qrCanvas.toDataURL());
}

function createQrWithLogo(data, fileName, callback) {
const qr = qrcode(4, 'Q');
qr.addData(data);
qr.make();
const qrCanvas = document.createElement('canvas');
const ctx = qrCanvas.getContext('2d');
qrCanvas.width = 200;
qrCanvas.height = 200;
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, qrCanvas.width, qrCanvas.height);
const qrImage = new Image();
qrImage.src = qr.createDataURL();
qrImage.onload = function() {
ctx.drawImage(qrImage, 0, 0, qrCanvas.width, qrCanvas.height);
if (logoFile) {
const logoImage = new Image();
const reader = new FileReader();
reader.onload = function(e) {
logoImage.src = e.target.result;
logoImage.onload = function() {
drawLogoOnQr(qrCanvas, logoImage, callback);
};
};
reader.readAsDataURL(logoFile);
} else {
callback(qrCanvas.toDataURL());
}
};
}

if (customQrCount && customQrCount > 0) {
for (let i = 0; i < customQrCount; i++) {
const randomString = generateRandomString();
createQrWithLogo(randomString, `${randomString}.png`, function(qrDataUrl) {
const qrItem = document.createElement('div');
qrItem.classList.add('qr-item');
const label = document.createElement('div');
label.innerText = `QR ${i + 1}: ${randomString}`;
const qrImage = document.createElement('img');
qrImage.src = qrDataUrl;
qrItem.appendChild(label);
qrItem.appendChild(qrImage);
outputSection.appendChild(qrItem);
qrCodes.push({ name: `${randomString}.png`, dataUrl: qrDataUrl });
});
}
}

lines.forEach((line, index) => {
createQrWithLogo(line.trim(), `QR_${index + 1}.png`, function(qrDataUrl) {
const qrItem = document.createElement('div');
qrItem.classList.add('qr-item');
const label = document.createElement('div');
label.innerText = `QR ${index + 1}: ${line.trim()}`;
const qrImage = document.createElement('img');
qrImage.src = qrDataUrl;
qrItem.appendChild(label);
qrItem.appendChild(qrImage);
outputSection.appendChild(qrItem);
qrCodes.push({ name: `QR_${index + 1}.png`, dataUrl: qrDataUrl });
});
});

setTimeout(() => {
if (qrCodes.length > 0) {
exportBtn.disabled = false;
}

exportBtn.onclick = function() {
const zip = new JSZip();
qrCodes.forEach(qr => {
const imgData = qr.dataUrl.split(',')[1];
zip.file(qr.name, imgData, { base64: true });
});
zip.generateAsync({ type: 'blob' }).then(function(content) {
saveAs(content, 'qr_codes.zip');
});
};
}, 1000);
});
157 changes: 157 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Arial', sans-serif;
}

body {
background-color: #181818;
color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

/* Container */
.container {
width: 90%;
max-width: 1100px;
}

.card {
background-color: #1e1e1e;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
border-radius: 12px;
padding: 20px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
color: #f0f0f0;
}

/* Input Section */
.input-section {
flex-basis: 45%;
}

.input-section h2 {
font-size: 24px;
margin-bottom: 15px;
color: #f0f0f0;
}

textarea {
width: 100%;
height: 150px;
padding: 10px;
border: 1px solid #333;
border-radius: 8px;
font-size: 16px;
margin-bottom: 15px;
background-color: #2c2c2c;
color: #f0f0f0;
}

textarea::placeholder {
color: #a0a0a0;
}

/* Options Section */
.options {
margin-bottom: 15px;
}

.option-group {
margin-bottom: 10px;
}

.option-group label {
display: block;
font-size: 14px;
margin-bottom: 5px;
color: #f0f0f0;
}

.option-group input {
padding: 8px;
width: 100%;
border: 1px solid #333;
border-radius: 8px;
background-color: #2c2c2c;
color: #f0f0f0;
}

/* Buttons */
.btn-primary {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
margin-top: 10px;
width: 100%;
}

.btn-primary:hover {
background-color: #0056b3;
}

.btn-secondary {
background-color: #28a745;
color: white;
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
margin-top: 10px;
width: 100%;
}

.btn-secondary:disabled {
background-color: #6c757d;
}

.btn-secondary:hover:not(:disabled) {
background-color: #218838;
}

/* Output Section */
.output-section {
flex-basis: 45%;
}

.output-section h2 {
font-size: 24px;
margin-bottom: 15px;
color: #f0f0f0;
}

.qr-container {
max-height: 400px;
overflow-y: auto;
border: 1px solid #333;
padding: 10px;
border-radius: 8px;
background-color: #2c2c2c;
}

.qr-container .qr-item {
display: flex;
align-items: center;
margin-bottom: 15px;
}

.qr-container .qr-item img {
margin-left: 10px;
width: 100px;
height: 100px;
border: 1px solid #444;
padding: 5px;
border-radius: 8px;
background-color: #1e1e1e;
}

0 comments on commit df4a14f

Please sign in to comment.