-
-
-
-
+
+
-
+
+
+
PNG
-
SVG
@@ -95,6 +98,182 @@
const size = document.getElementById('imgSize')
+ const qrTypes = {
+ url: {
+ name: 'URL / Text',
+ fields: [
+ {
+ id: 'urlBox',
+ placeholder: 'URL',
+ type: 'text'
+ }
+ ],
+ format: (vals) => vals[0],
+ inline: true,
+ helpLink: "https://github.com/zxing/zxing/wiki/Barcode-Contents"
+ },
+ wifi: {
+ name: 'WIFI',
+ fields: [
+ {
+ id: 'ssidBox',
+ placeholder: 'SSID',
+ type: 'text'
+ },
+ {
+ id: 'pwdBox',
+ placeholder: 'Password',
+ type: 'password'
+ }
+ ],
+ format: (vals) => `WIFI:S:${vals[0]};H:true;T:WPA2;P:${vals[1]};;`,
+ inline: true,
+ helpLink: "https://github.com/zxing/zxing/wiki/Barcode-Contents"
+ }
+ }
+
+ function genDropdown() {
+ const qrType = document.getElementById('qrType')
+ for (const key in qrTypes) {
+ const option = document.createElement('option')
+ option.value = key
+ option.textContent = qrTypes[key].name
+
+ qrType.appendChild(option)
+ }
+ }
+
+ function genInputsForSelectedOption() {
+ const qrType = document.getElementById('qrType').value
+ const inputs = document.getElementById('inputs')
+ inputs.innerHTML = ''
+
+ const config = qrTypes[qrType]
+ const fields = config.fields
+ const isInline = config.inline ?? config.inlineFields ?? false
+ const helpLink = (config.helpLink ?? '').trim()
+
+ const container = document.createElement('div')
+ container.classList.add('flex', 'rounded', 'border-gray-900', 'bg-gray-800', 'border-1', 'text-white', 'mb-2', 'w-full', 'max-w-full')
+
+ if (isInline) {
+ container.classList.add('flex-row', 'items-center', 'h-14')
+ } else {
+ container.classList.add('flex-row', 'items-stretch')
+ }
+
+ if (helpLink !== '') {
+ const help = document.createElement('a')
+ help.href = helpLink
+ help.target = '_blank'
+ help.rel = 'noopener noreferrer'
+ help.classList.add('p-2', 'block', 'flex', 'flex-row', 'items-center', 'justify-center', 'hover:bg-gray-700', 'shrink-0')
+
+ if (isInline) {
+ help.classList.add('h-full')
+ } else {
+ help.classList.add('self-stretch')
+ }
+
+ help.innerHTML = `
+
+ `
+ container.appendChild(help)
+ }
+
+ const fieldsContainer = document.createElement('div')
+ fieldsContainer.classList.add('flex', 'flex-1')
+
+ if (isInline) {
+ fieldsContainer.classList.add('flex-row', 'items-center', 'h-full')
+ } else {
+ fieldsContainer.classList.add('flex-col')
+ }
+
+ const generateBtn = document.createElement('button')
+ generateBtn.type = 'button'
+ generateBtn.textContent = 'Generate'
+ generateBtn.classList.add('pl-3', 'pr-3', 'border-l-gray-900', 'border-l-1', 'hover:bg-gray-700', 'shrink-0')
+
+ if (isInline) {
+ generateBtn.classList.add('h-full')
+ } else {
+ generateBtn.classList.add('self-stretch')
+ }
+
+ generateBtn.onclick = generateFromSelectedOption
+
+ fields.forEach((field, index) => {
+ const input = document.createElement('input')
+
+ input.type = field.type
+ input.placeholder = field.placeholder
+ input.id = field.id
+
+ if (isInline) {
+ input.classList.add('h-full', 'pl-3', 'text-current', 'bg-transparent', 'focus:outline-none', 'w-full')
+ } else {
+ input.classList.add('py-3', 'px-2', 'text-current', 'bg-transparent', 'focus:outline-none', 'w-full')
+ if (index > 0) {
+ input.classList.add('border-t-1', 'border-t-gray-700')
+ }
+ }
+
+ input.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter') {
+ e.preventDefault()
+ generateBtn.click()
+ }
+ })
+
+ fieldsContainer.appendChild(input)
+ })
+
+ container.appendChild(fieldsContainer)
+ container.appendChild(generateBtn)
+ inputs.appendChild(container)
+ }
+
+ function generateFromSelectedOption() {
+ const qrType = document.getElementById('qrType').value
+ const config = qrTypes[qrType]
+
+ const values = config.fields.map((field) => {
+ const el = document.getElementById(field.id)
+ return el ? el.value : ''
+ })
+
+ const val = config.format(values)
+ const qr = document.getElementById("qrcode")
+
+ qr.innerHTML = genSvg(val)
+ lastQuery = val
+ }
+
+ function setInitialLoading(isLoading) {
+ const loader = document.getElementById('initLoader')
+ const inputs = document.getElementById('inputs')
+ const qr = document.getElementById('qrcode')
+
+ if (!loader || !inputs || !qr) {
+ return
+ }
+
+ if (isLoading) {
+ loader.classList.remove('hidden')
+ inputs.classList.add('hidden')
+ qr.classList.add('hidden')
+ } else {
+ loader.classList.add('hidden')
+ inputs.classList.remove('hidden')
+ qr.classList.remove('hidden')
+ }
+ }
+
function genSvg(val) {
return new QRCode({
content: val,
@@ -119,49 +298,34 @@
return canvas.toDataURL('img/png')
}
- // Wifi QR Code
- // Format: WIFI:S:SSID_NAME;H:true;T:WPA2;P:PASSWORD;;
-
window.onload = () => {
// Check query params
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
-
- let btn = document.getElementById("genBtn")
- let link = document.getElementById("linkBox")
- let qr = document.getElementById("qrcode");
-
- let genWifiBtn = document.getElementById("genWifiBtn")
- let ssidBox = document.getElementById("ssidBox")
- let pwdBox = document.getElementById("pwdBox")
- // Standard QR
- btn.onclick = () => {
- qr.innerHTML = genSvg(link.value)
- lastQuery = link.value
- }
+ let qr = document.getElementById("qrcode");
+ setInitialLoading(true)
- // Wifi QR
- genWifiBtn.onclick = () => {
- const ssid = ssidBox.value
- const pwd = pwdBox.value
-
- const wifi = `WIFI:S:${ssid};H:true;T:WPA2;P:${pwd};;`
- qr.innerHTML = genSvg(wifi)
- lastQuery = wifi
- }
+ genDropdown();
+ document.getElementById('qrType').addEventListener('change', genInputsForSelectedOption)
+ genInputsForSelectedOption();
const qlink = params.link
- if(qlink && qlink.trim() !== '') {
- link.value = qlink
-
- qr.innerHTML = genSvg(qlink)
- lastQuery = qlink
- }
- else
+ if (qlink && qlink.trim() !== '') {
+ const urlField = document.getElementById('urlBox')
+ if (urlField) {
+ urlField.value = qlink
+ generateFromSelectedOption()
+ } else {
+ qr.innerHTML = genSvg(qlink)
+ lastQuery = qlink
+ }
+ } else {
qr.innerHTML = genSvg('https://google.com')
-
+ }
+ setInitialLoading(false)
+
// Download
var dlPng = document.getElementById('dlpng')
var dlSvg = document.getElementById('dlsvg')
@@ -170,27 +334,34 @@
const dataUrl = genPng(lastQuery)
const blob = await (await fetch(dataUrl)).blob()
const blobUrl = URL.createObjectURL(blob)
+
var link = document.createElement('a')
link.download = `${encodeURI(lastQuery)}.png`
link.href = blobUrl
+
document.body.appendChild(link)
link.click()
+
document.body.removeChild(link)
URL.revokeObjectURL(blobUrl)
}
dlSvg.onclick = async (e) => {
e.preventDefault()
- const svgBlob = new Blob([genSvg(lastQuery)], {type:"image/svg+xml"})
+ const svgBlob = new Blob([genSvg(lastQuery)], { type: "image/svg+xml" })
const svgUrl = URL.createObjectURL(svgBlob)
+
let link = document.createElement('a')
link.download = `${encodeURI(lastQuery)}.svg`
link.href = svgUrl
+
document.body.appendChild(link)
link.click()
+
document.body.removeChild(link)
URL.revokeObjectURL(svgUrl)
}
+
}