Add QR code demo tool

This commit is contained in:
Illya Marchenko 2024-04-19 21:25:31 +03:00
parent 34605ce9b9
commit 2d348d88a0
Signed by: stuzer05
GPG Key ID: A6ABAAA9268F9F4F
5 changed files with 1794 additions and 444 deletions

1874
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -12,6 +12,7 @@
"autoprefixer": "^10", "autoprefixer": "^10",
"axios": "^0.27.2", "axios": "^0.27.2",
"cronstrue": "^2.47.0", "cronstrue": "^2.47.0",
"easyqrcodejs": "^4.6.1",
"mitt": "^3.0.0", "mitt": "^3.0.0",
"pinia": "^2.0.14", "pinia": "^2.0.14",
"postcss": "^8.4.35", "postcss": "^8.4.35",

@ -40,6 +40,7 @@ export default {
'dummy_image': 'Dummy image', 'dummy_image': 'Dummy image',
'humans_txt': 'humans.txt generator', 'humans_txt': 'humans.txt generator',
'file_base64_encode_decode': 'File base64 encode/decode', 'file_base64_encode_decode': 'File base64 encode/decode',
// 'qr_code': 'QR code',
}, },
'Strings': { 'Strings': {
'fix_ru_en_keyboard': 'Fix ru-en keyboard', 'fix_ru_en_keyboard': 'Fix ru-en keyboard',

@ -31,6 +31,11 @@ const router = createRouter({
name: 'humans_txt', name: 'humans_txt',
component: () => import('../views/HumansTxt.vue'), component: () => import('../views/HumansTxt.vue'),
}, },
{
path: '/qr_code',
name: 'qr_code',
component: () => import('../views/QRCode.vue'),
},
/** /**
* String manipulation * String manipulation

357
src/views/QRCode.vue Normal file

@ -0,0 +1,357 @@
<template>
<h2 class="tool-title">QR code</h2>
<hr class="mt-5 mb-5">
<form @submit.prevent="generateQRCode">
<!-- Basic options -->
<div>
<label for="text">Text:</label>
<input type="text" id="text" v-model="toolData.options.text" />
</div>
<div>
<label for="width">Width:</label>
<input type="number" id="width" v-model.number="toolData.options.width" />
</div>
<div>
<label for="height">Height:</label>
<input type="number" id="height" v-model.number="toolData.options.height" />
</div>
<div>
<label for="colorDark">Dark Color:</label>
<input type="color" id="colorDark" v-model="toolData.options.colorDark" />
</div>
<div>
<label for="colorLight">Light Color:</label>
<input type="color" id="colorLight" v-model="toolData.options.colorLight" />
</div>
<div>
<label for="correctLevel">Correct Level:</label>
<select id="correctLevel" v-model="toolData.options.correctLevel">
<option value="L">L</option>
<option value="M">M</option>
<option value="Q">Q</option>
<option value="H">H</option>
</select>
</div>
<!-- dotScale options -->
<div>
<label for="dotScale">Dot Scale:</label>
<input type="number" id="dotScale" v-model.number="toolData.options.dotScale" step="0.1" min="0" max="1" />
</div>
<div>
<label for="dotScaleTiming">Dot Scale Timing:</label>
<input type="number" id="dotScaleTiming" v-model.number="toolData.options.dotScaleTiming" step="0.1" min="0" max="1" />
</div>
<div>
<label for="dotScaleTiming_H">Dot Scale Timing (Horizontal):</label>
<input type="number" id="dotScaleTiming_H" v-model.number="toolData.options.dotScaleTiming_H" step="0.1" min="0" max="1" />
</div>
<div>
<label for="dotScaleTiming_V">Dot Scale Timing (Vertical):</label>
<input type="number" id="dotScaleTiming_V" v-model.number="toolData.options.dotScaleTiming_V" step="0.1" min="0" max="1" />
</div>
<div>
<label for="dotScaleA">Dot Scale A:</label>
<input type="number" id="dotScaleA" v-model.number="toolData.options.dotScaleA" step="0.1" min="0" max="1" />
</div>
<div>
<label for="dotScaleAO">Dot Scale AO:</label>
<input type="number" id="dotScaleAO" v-model.number="toolData.options.dotScaleAO" step="0.1" min="0" max="1" />
</div>
<div>
<label for="dotScaleAI">Dot Scale AI:</label>
<input type="number" id="dotScaleAI" v-model.number="toolData.options.dotScaleAI" step="0.1" min="0" max="1" />
</div>
<!-- Quiet Zone options -->
<div>
<label for="quietZone">Quiet Zone:</label>
<input type="number" id="quietZone" v-model.number="toolData.options.quietZone" />
</div>
<div>
<label for="quietZoneColor">Quiet Zone Color:</label>
<input type="color" id="quietZoneColor" v-model="toolData.options.quietZoneColor" />
</div>
<!-- Logo options -->
<!-- Logo upload -->
<div>
<label for="logoUpload">Logo Upload:</label>
<input type="file" id="logoUpload" ref="logoUpload" @change="handleLogoUpload" accept="image/*" />
</div>
<div>
<label for="logoWidth">Logo Width:</label>
<input type="number" id="logoWidth" v-model.number="toolData.options.logoWidth" />
</div>
<div>
<label for="logoHeight">Logo Height:</label>
<input type="number" id="logoHeight" v-model.number="toolData.options.logoHeight" />
</div>
<div>
<label for="logoMaxWidth">Logo Max Width:</label>
<input type="number" id="logoMaxWidth" v-model.number="toolData.options.logoMaxWidth" />
</div>
<div>
<label for="logoMaxHeight">Logo Max Height:</label>
<input type="number" id="logoMaxHeight" v-model.number="toolData.options.logoMaxHeight" />
</div>
<div>
<label for="logoBackgroundColor">Logo Background Color:</label>
<input type="color" id="logoBackgroundColor" v-model="toolData.options.logoBackgroundColor" />
</div>
<div>
<label for="logoBackgroundTransparent">Logo Background Transparent:</label>
<input type="checkbox" id="logoBackgroundTransparent" v-model="toolData.options.logoBackgroundTransparent" />
</div>
<!-- Background Image options -->
<!-- Background Image upload -->
<div>
<label for="backgroundImageUpload">Background Image Upload:</label>
<input type="file" id="backgroundImageUpload" ref="backgroundImageUpload" @change="handleBackgroundImageUpload" accept="image/*" />
</div>
<div>
<label for="backgroundImageAlpha">Background Image Alpha:</label>
<input type="number" id="backgroundImageAlpha" v-model.number="toolData.options.backgroundImageAlpha" step="0.1" min="0" max="1" />
</div>
<div>
<label for="autoColor">Auto Color:</label>
<input type="checkbox" id="autoColor" v-model="toolData.options.autoColor" />
</div>
<div>
<label for="autoColorDark">Auto Color Dark:</label>
<input type="color" id="autoColorDark" v-model="toolData.options.autoColorDark" />
</div>
<div>
<label for="autoColorLight">Auto Color Light:</label>
<input type="color" id="autoColorLight" v-model="toolData.options.autoColorLight" />
</div>
<!-- Colorful options -->
<div>
<label for="PO">Position Outer Color:</label>
<input type="color" id="PO" v-model="toolData.options.PO" />
</div>
<div>
<label for="PI">Position Inner Color:</label>
<input type="color" id="PI" v-model="toolData.options.PI" />
</div>
<div>
<label for="PO_TL">Position Outer Color - Top Left:</label>
<input type="color" id="PO_TL" v-model="toolData.options.PO_TL" />
</div>
<div>
<label for="PI_TL">Position Inner Color - Top Left:</label>
<input type="color" id="PI_TL" v-model="toolData.options.PI_TL" />
</div>
<div>
<label for="PO_TR">Position Outer Color - Top Right:</label>
<input type="color" id="PO_TR" v-model="toolData.options.PO_TR" />
</div>
<div>
<label for="PI_TR">Position Inner Color - Top Right:</label>
<input type="color" id="PI_TR" v-model="toolData.options.PI_TR" />
</div>
<div>
<label for="PO_BL">Position Outer Color - Bottom Left:</label>
<input type="color" id="PO_BL" v-model="toolData.options.PO_BL" />
</div>
<div>
<label for="PI_BL">Position Inner Color - Bottom Left:</label>
<input type="color" id="PI_BL" v-model="toolData.options.PI_BL" />
</div>
<!-- Alignment Color options -->
<div>
<label for="AO">Alignment Outer Color:</label>
<input type="color" id="AO" v-model="toolData.options.AO" />
</div>
<div>
<label for="AI">Alignment Inner Color:</label>
<input type="color" id="AI" v-model="toolData.options.AI" />
</div>
<!-- Timing Pattern Color options -->
<div>
<label for="timing">Timing Color:</label>
<input type="color" id="timing" v-model="toolData.options.timing" />
</div>
<div>
<label for="timing_H">Timing Color (Horizontal):</label>
<input type="color" id="timing_H" v-model="toolData.options.timing_H" />
</div>
<div>
<label for="timing_V">Timing Color (Vertical):</label>
<input type="color" id="timing_V" v-model="toolData.options.timing_V" />
</div>
<!-- Title options -->
<div>
<label for="title">Title:</label>
<input type="text" id="title" v-model="toolData.options.title" />
</div>
<div>
<label for="titleFont">Title Font:</label>
<input type="text" id="titleFont" v-model="toolData.options.titleFont" />
</div>
<div>
<label for="titleColor">Title Color:</label>
<input type="color" id="titleColor" v-model="toolData.options.titleColor" />
</div>
<div>
<label for="titleBackgroundColor">Title Background Color:</label>
<input type="color" id="titleBackgroundColor" v-model="toolData.options.titleBackgroundColor" />
</div>
<div>
<label for="titleHeight">Title Height:</label>
<input type="number" id="titleHeight" v-model.number="toolData.options.titleHeight" />
</div>
<div>
<label for="titleTop">Title Top:</label>
<input type="number" id="titleTop" v-model.number="toolData.options.titleTop" />
</div>
<!-- Subtitle options -->
<div>
<label for="subTitle">Subtitle:</label>
<input type="text" id="subTitle" v-model="toolData.options.subTitle" />
</div>
<div>
<label for="subTitleFont">Subtitle Font:</label>
<input type="text" id="subTitleFont" v-model="toolData.options.subTitleFont" />
</div>
<div>
<label for="subTitleColor">Subtitle Color:</label>
<input type="color" id="subTitleColor" v-model="toolData.options.subTitleColor" />
</div>
<div>
<label for="subTitleTop">Subtitle Top:</label>
<input type="number" id="subTitleTop" v-model.number="toolData.options.subTitleTop" />
</div>
<!-- Event Handler options -->
<!-- You can add event handler options based on your specific requirements -->
<!-- Drawing method option -->
<div>
<label for="drawer">Drawer:</label>
<select id="drawer" v-model="toolData.options.drawer">
<option value="canvas">Canvas</option>
<option value="svg">SVG</option>
</select>
</div>
<button type="submit">Generate QR Code</button>
</form>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<div ref="qrcodeContainer"></div>
</div>
</template>
<script>
import QRCode from 'easyqrcodejs';
export default {
data() {
return {
toolData: {
options: {
text: 'https://github.com/ushelp/EasyQRCodeJS',
width: 256,
height: 256,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H,
dotScale: 1,
dotScaleTiming: 1,
dotScaleTiming_H: 0,
dotScaleTiming_V: 0,
dotScaleA: 1,
dotScaleAO: 0,
dotScaleAI: 0,
quietZone: 0,
quietZoneColor: 'rgba(0,0,0,0)',
logo: '',
logoWidth: 0,
logoHeight: 0,
logoMaxWidth: 0,
logoMaxHeight: 0,
logoBackgroundColor: '#ffffff',
logoBackgroundTransparent: false,
backgroundImage: '',
backgroundImageAlpha: 1,
autoColor: false,
autoColorDark: 'rgba(0, 0, 0, .6)',
autoColorLight: 'rgba(255, 255, 255, .7)',
PO: '',
PI: '',
PO_TL: '',
PI_TL: '',
PO_TR: '',
PI_TR: '',
PO_BL: '',
PI_BL: '',
AO: '',
AI: '',
timing: '',
timing_H: '',
timing_V: '',
title: '',
titleFont: 'bold 16px Arial',
titleColor: '#000',
titleBackgroundColor: '#fff',
titleHeight: 0,
titleTop: 30,
subTitle: '',
subTitleFont: '14px Arial',
subTitleColor: '#4F4F4F',
subTitleTop: 0,
drawer: 'canvas',
},
},
};
},
methods: {
result() {
},
handleLogoUpload(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
this.toolData.options.logo = e.target.result;
};
reader.readAsDataURL(file);
}
},
handleBackgroundImageUpload(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
this.toolData.options.backgroundImage = e.target.result;
};
reader.readAsDataURL(file);
}
},
generateQRCode() {
// Clear previous QR code
this.$refs.qrcodeContainer.innerHTML = '';
// Generate the QR code
const qrcode = new QRCode(this.$refs.qrcodeContainer, this.toolData.options);
},
}
}
</script>
<style lang="scss">
</style>