qrcode.js を使って、QRコードを作成する

2023年5月12日

 qrcode.js を利用して、QRコードを作成するツールを作ってみました。
文字数
0
バイト数
0
最大バイト数
0
バージョン
---
セル数
---
誤り訂正レベル

ソース

・html
<div id="p2002" class="v-flex">
	<div class="h-flex">
		<div class="qr fx-grow"></div>
		<div class="info v-flex">
			<div class="v-flex item"><div class="key">文字数</div><div class="value info-chars">0</div></div>
			<div class="v-flex item"><div class="key">バイト数</div><div class="value info-bytes">0</div></div>
			<div class="v-flex item"><div class="key">最大バイト数</div><div class="value info-maxbytes">0</div></div>
			<div class="v-flex item"><div class="key">バージョン</div><div class="value info-typenum">&#x2d;&#x2d;&#x2d;</div></div>
			<div class="v-flex item"><div class="key">セル数</div><div class="value info-modules">&#x2d;&#x2d;&#x2d;</div></div>
			<div class="v-flex item"><div class="key">誤り訂正レベル</div><div class="value info-correct"><button class="btn correct"></button></div></div>
		</div>
	</div>
	<div><textarea class="text" rows="4" spellcheck="false" placeholder="文字を入力してください"></textarea></div>
	<div class="chars"></div>
</div>
・css
.h-flex { display: flex; flex-direction: row }
.v-flex { display: flex; flex-direction: column }
.fx-grow { flex-grow: 1}

.l { text-align: left }
.r { text-align: right }

.btn {
	padding: 0.5rem 0rem;
	margin: 0.5rem 0;
	width: 8rem;
	background-color: #CCC;
	border-radius: 5px;
	transition: all 0.2s ease-in-out;
}

.btn:active {
	background-color: #AAA;
	transform: scale(1.2);
	transition: 0.1s;
}

.item {
	min-width: 10rem;
}

.key {
	text-align: left;
	font-size: 80%;
	font-weight: bold;
}

.value {
	text-align: right;
}

.qr {
	padding: 48px;
	background-color: #FFF;
}

.text {
	word-break: break-all;
	line-height: 1.25;	
	width: 100%;
}
・javascript
<script src="qrcode.min.js" defer></script>
jQuery(($) => {
	'use strict'

	const te = new TextEncoder();
	const qrTable = [
		[QRCode.CorrectLevel.L, 'L (7%)', 2953],
		[QRCode.CorrectLevel.M, 'M (15%)', 2331],
		[QRCode.CorrectLevel.Q, 'Q (25%)', 1663],
		[QRCode.CorrectLevel.H, 'H (30%)', 1273]
	];
	const qrData = {
		text: '',
		width: 256,
		height: 256,
		correctLevel: QRCode.CorrectLevel.M,
	}
	let idKeyup = null;
	let myCorrectLevel = 1;

	main();

	function main() {
		$('.correct').click(() => {
			myCorrectLevel = (myCorrectLevel + 1) % 4;
			setCorrectLevel(myCorrectLevel);
			
			updateQR();
		});

		$('.text').on('keyup', () => {
			if (idKeyup !== null) clearTimeout(idKeyup);
			idKeyup = setTimeout(updateQR, 250);

			const s = $('.text').val();
			setValue('.info-chars', s.length);
			setValue('.info-bytes', getFinalBytes(s));
		});

		setCorrectLevel(myCorrectLevel);
	}

	function getFinalBytes(s) {
		let padSize = 0;

		for (let i = 0; i < s.length; i++) {
			const v = s.charCodeAt(i);
			if (v >= 0x80) {
				padSize = 3;
				break;
			}
		}
		return padSize + te.encode(s).length
	}

	function setCorrectLevel(v) {
		qrData.correctLevel = qrTable[v][0];
		$('.correct').text(qrTable[v][1]);
		setValue('.info-maxbytes', qrTable[v][2]);
	}

	function updateQR() {
		let s1 = null, s2 = null;

		idKeyup = null;

		qrData.text = $('.text').val();
		$('.qr').empty();
		
		try {
			const qr = new QRCode($('.qr')[0], qrData);
			const o = qr._oQRCode;
			if (o !== null) {
				s1 = o.moduleCount;
				s2 = o.typeNumber;
			}
		} catch (e) {
		}
		setValue('.info-modules', s1);
		setValue('.info-typenum', s2);
	}

	function setValue(selector, num) {
		const s = num === null ? '---' : num.toLocaleString();
		$(selector).text(s);
	}
});

javascript,qrcode

Posted by plkl