Add QR code tool
This commit is contained in:
parent
2d348d88a0
commit
339470df5f
@ -12,12 +12,21 @@ input[type=text], input[type=number], input[type=url], textarea {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
input:disabled, textarea:disabled {
|
||||
background-color: #ddd;
|
||||
color: linen;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
select {
|
||||
min-width: 100px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
padding: 0 5px;
|
||||
|
@ -16,6 +16,7 @@
|
||||
<div class="flex flex-col mb-2">
|
||||
<p><i>Other</i></p>
|
||||
<a href="https://gist.stuzer.link/" class="ml-4" tag="button">Gist</a>
|
||||
<a href="https://cyberchef.tools.stuzer.link/" class="ml-4" tag="button">Cyberchef</a>
|
||||
<a href="https://pdf.tools.stuzer.link/" class="ml-4" tag="button">PDF tools</a>
|
||||
</div>
|
||||
</nav>
|
||||
@ -40,7 +41,7 @@ export default {
|
||||
'dummy_image': 'Dummy image',
|
||||
'humans_txt': 'humans.txt generator',
|
||||
'file_base64_encode_decode': 'File base64 encode/decode',
|
||||
// 'qr_code': 'QR code',
|
||||
'qr_code': 'QR code',
|
||||
},
|
||||
'Strings': {
|
||||
'fix_ru_en_keyboard': 'Fix ru-en keyboard',
|
||||
|
@ -2,253 +2,87 @@
|
||||
<h2 class="tool-title">QR code</h2>
|
||||
<hr class="mt-5 mb-5">
|
||||
|
||||
<form @submit.prevent="generateQRCode">
|
||||
<!-- Basic options -->
|
||||
<!-- Type options -->
|
||||
<div class="input-group">
|
||||
<label for="text">Data:</label>
|
||||
<textarea id="data" v-model="toolData.options.text" v-on:keyup="result"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Basic options -->
|
||||
<div class="input-group">
|
||||
<label for="width">Width:</label>
|
||||
<input id="width" v-model.number="toolData.options.width" v-on:change="result" v-on:keyup="result" type="number">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="height">Height:</label>
|
||||
<input id="height" v-model.number="toolData.options.height" v-on:change="result" v-on:keyup="result" type="number">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="height">White border:</label>
|
||||
<input id="quietZone" v-model.number="toolData.options.quietZone" v-on:change="result" v-on:keyup="result" type="number">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="correctLevel">Correct Level:</label>
|
||||
<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">
|
||||
<select id="correctLevel" v-model="toolData.options.correctLevel" v-on:change="result">
|
||||
<option value="L">L</option>
|
||||
<option value="M">M</option>
|
||||
<option value="Q">Q</option>
|
||||
<option value="H">H</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- dotScale options -->
|
||||
<!-- Logo options -->
|
||||
<div class="input-group">
|
||||
<label for="logoUpload">Logo Upload:</label>
|
||||
<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" />
|
||||
<input type="file" id="logoUpload" ref="logoUpload" @change="handleLogoUpload" accept="image/*">
|
||||
<button @click="removeLogo">🞩</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quiet Zone options -->
|
||||
<!-- Background Image options -->
|
||||
<div class="input-group">
|
||||
<label for="backgroundImageUpload">Background Image Upload:</label>
|
||||
<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" />
|
||||
<input type="file" id="backgroundImageUpload" ref="backgroundImageUpload" @change="handleBackgroundImageUpload" accept="image/*">
|
||||
<button @click="removeBackgroundImage">🞩</button>
|
||||
</div>
|
||||
</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>
|
||||
<div class="input-group">
|
||||
<label for="backgroundImageAlpha">Background Image Alpha:</label>
|
||||
<input id="backgroundImageAlpha" v-model.number="toolData.options.backgroundImageAlpha" step="0.1" min="0" max="1" v-on:change="result" v-on:keyup="result" type="number">
|
||||
</div>
|
||||
|
||||
<!-- Background Image options -->
|
||||
<!-- Background Image upload -->
|
||||
<!--
|
||||
<div class="input-group">
|
||||
<label for="autoColor">Auto Color:</label>
|
||||
<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" />
|
||||
<input id="autoColor" v-model="toolData.options.autoColor" v-on:change="result" type="checkbox">
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- Colorful options -->
|
||||
<!-- Drawing method option -->
|
||||
<div class="input-group">
|
||||
<label for="drawer">Drawer:</label>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<hr class="mt-5 mb-5">
|
||||
|
||||
<div class="input-group">
|
||||
<label for="result">Result</label>
|
||||
<label>Result</label>
|
||||
|
||||
<div ref="qrcodeContainer"></div>
|
||||
</div>
|
||||
@ -256,77 +90,61 @@
|
||||
|
||||
<script>
|
||||
import QRCode from 'easyqrcodejs';
|
||||
import { unproxy } from "../utils/unproxy";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
toolData: {
|
||||
options: {
|
||||
text: 'https://github.com/ushelp/EasyQRCodeJS',
|
||||
text: '',
|
||||
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)',
|
||||
correctLevel: 'L',
|
||||
logo: '',
|
||||
logoWidth: 0,
|
||||
logoHeight: 0,
|
||||
logoMaxWidth: 0,
|
||||
logoMaxHeight: 0,
|
||||
logoBackgroundColor: '#ffffff',
|
||||
logoBackgroundTransparent: false,
|
||||
quietZone: 10,
|
||||
logoBackgroundTransparent: true,
|
||||
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,
|
||||
autoColor: true,
|
||||
drawer: 'canvas',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.toolData.options.text = ' ';
|
||||
this.result();
|
||||
this.toolData.options.text = '';
|
||||
},
|
||||
methods: {
|
||||
result() {
|
||||
// Clear previous QR code
|
||||
this.$refs.qrcodeContainer.innerHTML = '';
|
||||
|
||||
let options = unproxy(this.toolData.options);
|
||||
|
||||
// convert correction levels
|
||||
options.correctLevel = {
|
||||
'L': QRCode.CorrectLevel.L,
|
||||
'M': QRCode.CorrectLevel.M,
|
||||
'Q': QRCode.CorrectLevel.Q,
|
||||
'H': QRCode.CorrectLevel.H,
|
||||
}[options.correctLevel];
|
||||
|
||||
console.log(options.correctLevel);
|
||||
|
||||
// Generate the QR code
|
||||
new QRCode(this.$refs.qrcodeContainer, options);
|
||||
},
|
||||
|
||||
handleLogoUpload(event) {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
this.toolData.options.logo = e.target.result;
|
||||
this.result();
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
@ -337,16 +155,19 @@ export default {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
this.toolData.options.backgroundImage = e.target.result;
|
||||
this.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);
|
||||
removeLogo() {
|
||||
this.toolData.options.logo = '';
|
||||
this.result();
|
||||
},
|
||||
removeBackgroundImage() {
|
||||
this.toolData.options.backgroundImage = '';
|
||||
this.result();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user