GAS - QRコード生成ウェブアプリを作成
初めに
GAS を使って、QRコードを生成する Web アプリを公開したので、紹介いたします。
Index
コード全文
Code.gs
// Code.gs function doGet() { return HtmlService.createTemplateFromFile('index') .evaluate() .setTitle('QRコード生成アプリ') .addMetaTag('viewport', 'width=device-width, initial-scale=1'); } function getCustomQRCode(url, color, backgroundColor, size) { var apiUrl = 'https://api.qrserver.com/v1/create-qr-code/?data=' + encodeURIComponent(url); if (color) { apiUrl += '&color=' + encodeURIComponent(color); } if (backgroundColor) { apiUrl += '&bgcolor=' + encodeURIComponent(backgroundColor); } if (size) { apiUrl += '&size=' + encodeURIComponent(size); } Logger.log(apiUrl); return apiUrl; } // ログ確認用 function logGetCustomQRCode() { var url = "url"; getCustomQRCode(url, "red", "blue", "300x300"); }
index.html
<!-- index.html --> <!DOCTYPE html> <html> <head> <base target="_top"> <title>QRコードクリエイト</title> <!-- Materialize CSS CDN --> <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet"> <!-- Font Awesome CDN --> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet"> <!-- Pickr CSS CDN --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css"/> <!-- 'classic' theme --> <!-- 外部のスタイルシートを読み込む --> <?!= HtmlService.createHtmlOutputFromFile('style').getContent(); ?> </head> <body> <header> <h3 class="center-align" style="color: white">QRコードクリエイト</h3> </header> <div class="container"> <form id="urlForm" class="col s12"> <div class="row"> <div class="input-field col s12"> <input type="text" id="urlInput" class="validate" required> <label for="urlInput">URLを入力してください</label> </div> </div> <h6>各種設定を入力してください</h6> <p>デフォルト設定は色:黒、背景色:白、サイズ:200x200</p> <div class="row"> <div class="input-field col s12"> <h6>色</h6> <div class="color-picker-container" style="display: flex; align-items: center;"> <div style="padding: 10px; border: 2px solid #000;"> <input type="text" id="colorInput" class="validate" placeholder="色を選択"> </div> <p id="colorRgb" style="margin-left: 10px;"></p> </div> </div> </div> <div class="row"> <div class="input-field col s12"> <h6>背景色</h6> <div class="color-picker-container" style="display: flex; align-items: center;"> <div style="padding: 10px; border: 2px solid #000;"> <input type="text" id="bgColorInput" class="validate" placeholder="背景色を選択"> </div> <p id="bgColorRgb" style="margin-left: 10px;"></p> </div> </div> </div> <div class="row"> <div class="input-field col s12"> <h6>サイズ</h6> <input type="range" id="sizeSlider" min="10" max="1000" step="1" value="200"> <output id="sizeValue">200x200</output> </div> </div> <div class="row"> <div class="input-field col s12"> <button class="btn waves-effect waves-light" type="submit">QRコードを生成</button> </div> </div> </form> <div class="row"> <div id="qrCode" class="center-align"></div> </div> </div> <!-- Materialize JS CDN --> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> <!-- Font Awesome JS CDN --> <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js"></script> <!-- Pickr JS CDN --> <script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js"></script> <script> let colorCode; let bgColorCode; document.getElementById('urlForm').addEventListener('submit', function(e) { e.preventDefault(); var url = document.getElementById('urlInput').value; var color = document.getElementById('colorInput'); var bgColor = document.getElementById('bgColorInput'); var size = document.getElementById('sizeSlider').value; var sizeCode = size + "x" + size; generateQRCode(url, colorCode, bgColorCode, sizeCode); }); function generateQRCode(url, color, bgColor, size) { google.script.run.withSuccessHandler(displayQRCode).getCustomQRCode(url, color, bgColor, size); } function displayQRCode(qrCodeUrl) { var qrCodeDiv = document.getElementById('qrCode'); qrCodeDiv.innerHTML = '<img src="' + qrCodeUrl + '" alt="QR Code">'; } document.addEventListener('DOMContentLoaded', function() { // 色を選択するinput要素を取得する const colorInput = document.getElementById('colorInput'); const bgColorInput = document.getElementById('bgColorInput'); const colorRgb = document.getElementById('colorRgb'); const bgColorRgb = document.getElementById('bgColorRgb'); // 初期値の入力 colorRgb.textContent = "RGB:(0, 0, 0), #000000"; bgColorRgb.textContent = "RGB:(255, 255, 255), #FFFFFF"; // Pickrをインスタンス化する const pickr = Pickr.create({ el: colorInput, theme: 'classic', // ピッカーのテーマを選択 default: '#000000', // 初期の色を設定 comparison: false, swatches: [ '#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF' // 予め定義され たカラーパレット ], components: { preview: true, opacity: false, hue: true, interaction: { input: true, save: true } } }); const pickrBg = Pickr.create({ el: bgColorInput, theme: 'classic', default: '#FFFFFF', comparison: false, swatches: [ '#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF' ], components: { preview: true, opacity: false, hue: true, interaction: { input: true, save: true } } }); pickr.on('change', (color) => { const rgba = color.toRGBA(); const rgb = `RGB:(${Math.round(rgba[0])}, ${Math.round(rgba[1])}, ${Math.round(rgba[2])}), ${color.toHEXA().toString()}`; //末尾にカラーコードを表示 colorCode = Math.round(rgba[0]) + "-" + Math.round(rgba[1]) + "-" + Math.round(rgba[2]); colorRgb.textContent = rgb; }); pickrBg.on('change', (color) => { const rgba = color.toRGBA(); const rgb = `RGB:(${Math.round(rgba[0])}, ${Math.round(rgba[1])}, ${Math.round(rgba[2])}), ${color.toHEXA().toString()}`; bgColorCode = Math.round(rgba[0]) + "-" + Math.round(rgba[1]) + "-" + Math.round(rgba[2]); bgColorRgb.textContent = rgb; }); }); document.addEventListener('DOMContentLoaded', function() { const sizeSlider = document.getElementById('sizeSlider'); const sizeValue = document.getElementById('sizeValue'); sizeSlider.addEventListener('input', function() { sizeValue.textContent = sizeSlider.value + "x" + sizeSlider.value; }); }); </script> </body> </html>
styleシート
<style> header { background-color: #26a69a; /* ここに背景色のカラーコードを入力してください */ padding: 20px; /* 必要に応じて余白を調整 */ } .center-align { text-align: center; } .qr-code-container { position: relative; display: inline-block; } </style>
作成の動機
URLをQRコード化する機会がありますが、一般に公開したくないURLをQRコード化する場合、ネット上にあるQRコード作成サイトを使うことは危険であるため、自分で作ってしまえばよいと思い、作成しました。
解説
QR code API を使ったQRコードの生成
QR code API を使用し、URLからQRコードを作成しています。
// Code.gs から抜粋 function getCustomQRCode(url, color, backgroundColor, size) { var apiUrl = 'https://api.qrserver.com/v1/create-qr-code/?data=' + encodeURIComponent(url); if (color) { apiUrl += '&color=' + encodeURIComponent(color); } if (backgroundColor) { apiUrl += '&bgcolor=' + encodeURIComponent(backgroundColor); } if (size) { apiUrl += '&size=' + encodeURIComponent(size); } Logger.log(apiUrl); return apiUrl; }
Code.gs の getCustomQRCode(url, color, backgroundColor, size) 関数では、フロントエンドから URL、色、背景色、サイズをパラメータとして取得し、apiURLを返しています。
<!-- index.html の <script> から抜粋 --> document.getElementById('urlForm').addEventListener('submit', function(e) { e.preventDefault(); var url = document.getElementById('urlInput').value; var color = document.getElementById('colorInput'); var bgColor = document.getElementById('bgColorInput'); var size = document.getElementById('sizeSlider').value; var sizeCode = size + "x" + size; generateQRCode(url, colorCode, bgColorCode, sizeCode); }); function generateQRCode(url, color, bgColor, size) { google.script.run.withSuccessHandler(displayQRCode).getCustomQRCode(url, color, bgColor, size); } function displayQRCode(qrCodeUrl) { var qrCodeDiv = document.getElementById('qrCode'); qrCodeDiv.innerHTML = '<img src="' + qrCodeUrl + '" alt="QR Code">'; }
フロントエンドでは、submit ボタンを押すと、イベントが発生し generateQRCode() を実行します。generateQRCode() では、先ほど紹介した Code.gs にある getCustomQRCode() を実行し、引数である apiUrl をdisplayQRCode() 関数のパラメータ(qrCodeUrl)として受け取ります。受け取った apiUrl を画像として表示します。
Pickr を使った色の取得
Pickr を使って、下の画像のようにカラーピッカーを表示させ、選択した色のデータを取得することができます。
特筆すべき部分は次の2か所です。
<!-- index.html のカラーピッカー取得部分 --> <input type="text" id="colorInput" class="validate" placeholder="色を選択"> <!-- 中略 --> <!-- <Script> のPickrのインスタンス化部分 --> // Pickrをインスタンス化する const pickr = Pickr.create({ el: colorInput, theme: 'classic', // ピッカーのテーマを選択 default: '#000000', // 初期の色を設定 comparison: false, swatches: [ '#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF' // 予め定義され たカラーパレット ], components: { preview: true, opacity: false, hue: true, interaction: { input: true, save: true } } });
通常の input の表示の仕方ではなく、カラーピッカーの形に表示されるのは、Pickr のインスタンス化の部分で設定されているからです。el で id を指定し、インスタンスの設定をしています。