[Node.js] おみくじQRコードを作成する

前回はアニメーションするQRコードを作成しましたが、今回はその応用です。時間とともにQRコードの情報が変化する「おみくじ」を作ってみたいと思います。

雑にいうと「ルーレット」ですね。すごい勢いでQRコードの内容が切り替わっていく中、その一瞬をQRコードリーダー読み取ることで、利用者から見るとランダムな結果が得られるというヤツです。

おみくじQRを作成する

準備

前回と同じです。 適当なディレクトリ作成し、package.jsonを作成後に、node-qrcodenode-canvasモジュール、GIFアニメを簡単に作成できるgifencoderをインストールします。

$ mkdir qr-anime && cd qr-anime
$ npm init
$ npm install qrcode canvas gifencoder

QRコードを生成する

原理的には前回と同じなのですが、今回はフレーム毎にQRコードの方が変化している点ですね。

ポイントは文字数をなるべく同じにしないと、QRをコードの密度がフレーム毎に変わって見栄えが悪くなるところでしょうか。

const QRCode = require('qrcode');
const { createCanvas } = require('canvas');
const GIFEncoder = require('gifencoder');
const fs = require('fs');

const WIDTH  = 200;               // 画像サイズ X
const HEIGHT = 200;               // 画像サイズ Y
const GIFFILE = 'OmikujiQR.gif';  // 出力ファイル名


// QRコードの設定準備
const segments = [
  [{data:"【大吉】\n", mode:"kanji"}, {data:"褒美としてオプーナを買う権利をやろう",   mode:"kanji"}],
  [{data:"【吉】\n",   mode:"kanji"}, {data:"近所の野良猫がお腹をモフらせてくれる",   mode:"kanji"}],
  [{data:"【中吉】\n", mode:"kanji"}, {data:"何でもないようなことが幸せだったと思う", mode:"kanji"}],
  [{data:"【小吉】\n", mode:"kanji"}, {data:"ジョジョ立ちを荒木先生に褒められる",     mode:"kanji"}],
  [{data:"【凶】\n",   mode:"kanji"}, {data:"普段仲の良い近所の野良猫が他人行事",     mode:"kanji"}],
  [{data:"【大凶】\n", mode:"kanji"}, {data:"タンスに小指をぶつける喜びに目覚める",   mode:"kanji"}],
];
const options = {
  width: WIDTH,
  errorCorrectionLevel: 'L'
};

// アニメGIF設定
const encoder = new GIFEncoder(WIDTH, HEIGHT);
encoder.createReadStream().pipe( fs.createWriteStream(GIFFILE) );
encoder.start();
encoder.setRepeat(0);   // 0:リピートあり, -1:なし
encoder.setDelay(110);  // フレーム間隔(ミリ秒)
encoder.setQuality(10); // 画像品質

// canvas準備
const canvas = createCanvas(WIDTH, HEIGHT);
const ctx = canvas.getContext('2d');

// フレーム生成
for( let i=0; i<segments.length; i++ ){
  // QRコード生成
  ctx.clearRect(0, 0, canvas.width, canvas.height);  //リセット
  QRCode.toCanvas(canvas, segments[i], options);

  // フレームに追加
  encoder.addFrame(ctx);
}

encoder.finish();

参考ページ

ハンズオンNode.js

ハンズオンNode.js

Amazon