Algorithm & Canvas Composition
デザインと読み取り精度を両立する
QRコード合成のハック
「QRコードの中央に猫を置きたい」という直感的なニーズを支えるのは、Canvas APIによる多層描画と、QRコードの数学的な復元能力の最大活用です。
1. 誤り訂正レベル「H」による情報の欠損補完
QRコードには一部が汚れたり隠れたりしてもデータを復元できる「誤り訂正機能」が備わっています。本ツールでは、中央にアイコンを合成することを前提としているため、このレベルを最高設定の Level H に固定しています。
これにより、QRコード全体の約30%が隠れても理論上は読み取りが可能です。あえて最高レベルを選択することで、デザインの自由度(アイコンのサイズ感)と、実用的なスキャン精度をトレードオフさせずに実装しています。
// QRコード生成のパラメータ最適化
await QRCode.toCanvas(tempCanvas, text, {
// 誤り訂正レベルを最高(H)に固定することで
// 中央のアイコン合成によるデータ欠損を許容する
errorCorrectionLevel: 'H',
width: QR_SIZE_CONST,
color: {
dark: selectedColor,
light: "#ffffff"
}
}); 2. Canvasを用いた「背景マスク付き」重層描画
単純にQRコードの上に絵文字を重ねるだけでは、QRのドットパターンと絵文字が干渉し、視認性が著しく低下します。本ツールでは、アイコンの下に「白い円形の背景」を一段挟むことで、アイコンの輪郭を明確にし、同時にQRコードの読み取りセンサーが「ここはデータではなくノイズ(無視して良い場所)」と判断しやすくしています。
また、Canvasの ctx.save() と ctx.restore() を活用し、アイコン描画時のみ影(shadow)を適用することで、フラットなQRコードの中でアイコンだけが浮き上がるようなUXを実現しています。
// アイコンの合成処理(概念コード)
function drawDecoratedIcon(ctx, centerX, centerY) {
const iconAreaSize = // 独自の比率で算出
ctx.save();
// 1. 背面に白い円形を描画してQRドットを隠蔽
ctx.beginPath();
ctx.arc(centerX, centerY, iconAreaSize / 2, 0, Math.PI * 2);
ctx.fillStyle = '#ffffff';
ctx.fill();
// 2. アイコン(Emoji)の描画設定
ctx.font = `bold ${/* チューニングされたフォントサイズ */}px sans-serif`;
// 3. 視認性を上げるための独自の影処理
ctx.shadowColor = 'rgba(0, 0, 0, 0.15)';
ctx.shadowBlur = // 動的なしきい値
ctx.fillText(selectedIcon, centerX, centerY);
ctx.restore();
} Developer's Note
このツールで一番こだわったのは、「リアルタイム性」です。ユーザーがURLを一文字入力するたびに、裏側ではオフスクリーン・キャンバスでQRコードを再生成し、アイコンを合成し、最終的なプレビュー用のImage要素にデータを流し込んでいます。
一見重そうな処理ですが、最新のブラウザのCanvas APIは非常に高速で、800px四方の高解像度出力であっても、人間が遅延を感じないレベルで再描画が可能です。複雑なライブラリに頼りすぎず、Canvasという標準の武器を使い倒すことで、軽量かつ高機能なツールに仕上げることができました。