無精・短気・傲慢

perlの事 いろいろ

JavaScriptで選択したファイルを背景画像にする

HTMLのinputで選択した画像ファイルをJavaScriptでページの背景画像に設定したいより

サンプル GitHub

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<title>JavaScriptで選択したファイルを背景画像にする</title>
</head>
<body>
<script>
window.addEventListener('DOMContentLoaded', ()=>{
  const f=document.querySelector('#f');
  f.addEventListener('change',()=>{
    const content = f.files[0];
    const blob=new Blob([content],{type:f.type});
    document.body.style.backgroundImage=`url(${URL.createObjectURL(blob)})`;
  });
});
</script>
<input type="file" id="f">
</body>
</html>

入力できるプルダウンボックス(セレクトボックス)

入力できるプルダウンボックス(セレクトボックス)

$('.free_dropdown').on('click focus', function () {

//「input」要素の「data-options」をカンマで分割し、配列にする。
var options = $(this).data("options").split(',');

$(this).autocomplete({
		source: options,
		minLength: 0,  // 「0」を設定したら、全ての項目を表示する。
		delay : 1,
		autoFocus: false,
		scroll:true,
        position:{ my : "right top", at: "right bottom", collision: "flip" } //不具合対応

});

$(this).autocomplete("search", "");//この行を入れないと、初回にプルダウンボックス(セレクトボックス)が効かないという不具合がある

});

実装してみる

サンプル

<html lang="ja">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
       <title>入力できるプルダウンボックス</title>
       <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
       <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
       <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
   </head>
   <body>
       <h1>入力できるプルダウンボックス</h1>
       全表示:<input type=text id=in01 name=in01 class="suggest"><br>
       検 索:<input type=text id=in02 name=in02 class="suggest">
       <script>
           var suggestList01 = ['perl','ruby','Python','PHP','javaScript','AWK','bash','java','COBOL','C','C++',];
           $('#in01').autocomplete({
               minLength: 0,
               source: function(req,res) {
                   res(suggestList01);
               },
           });
           $('#in02').autocomplete({
               minLength: 0,
               source: function(req,res) {
                   res($.grep(suggestList01,function(v){
                       return v.toLowerCase().indexOf(req.term.toLowerCase()) >= 0;
                       })
                   );;
               },
           });
           $(document).on('focusin','.suggest',function() {
               $(this).autocomplete('search','');
           });
       </script>
   </body>
</html>

ブラウザでQRコードを書いたり読んだり

ブラウザだけでQRコードを読んだり書いたり出来ます。

QRコードを作成し表示する

jquery-qrcode.jsを使いQRコードを作成し表示する。

<script src="js/jquery-qrcode-0.18.0.min.js"></script>

<div id="qrcode"></div>
<script>
$('#qrcode').qrcode({width: 64, height: 64, text: "information"});
</script>

QRコードを読む

jsQR.jsを使いスマートホン等のカメラでQRコードを読み込む。

<script src="https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js"></script>

       <canvas id="canvas" hidden></canvas>
       <script>
           const video = document.createElement('video');
           const canvasElement = document.getElementById('canvas');
           const canvas = canvasElement.getContext('2d');
           const loading = document.getElementById('loading');
           let isReadQR = false;
       
           //QRコードを読む
           function qrRead() {
               isReadQR = false;
               navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
               .then((stream) => {
                   video.srcObject = stream;
                   video.setAttribute('playsinline', true);
                   video.play();
                   requestAnimationFrame(tick);
               });
           }
           
           function tick() {
             if (video.readyState === video.HAVE_ENOUGH_DATA) {
               loading.hidden = true;
               canvasElement.hidden = false;
               canvasElement.height = video.videoHeight;
               canvasElement.width = video.videoWidth;
               canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
               var imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
               var code = jsQR(imageData.data, imageData.width, imageData.height, {
                 inversionAttempts: 'dontInvert',
               });
               if (code && !isReadQR) {  //読み込めたら終了する
                   isReadQR = true;
               }
             }
             if(!isReadQR){
               requestAnimationFrame(tick);  //読み込めていない時は繰り返す
             }
           }
       </script>
<html lang="ja">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
       <title>QRコード読んだり書いたり</title>
       <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
       <script src="js/jquery-qrcode-0.18.0.min.js"></script>
       <script src="https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js"></script>
       <style>
       body {
         max-width: 800px;
         margin: auto;
         padding: 1rem;
         font-size: 14px;
         text-align: center;
       }
       </style>
   </head>
   <body>
       <textarea id=qrinput name=qrinput rows=5 cols=40></textarea>
       <br>
       <button id="qrON">QRコードを読む</button>
       <br><br>
       <div id="qrcode"></div>
       <div id="loading">ブラウザのカメラの使用を許可してください。</div>
       <br>
       <canvas id="canvas" hidden></canvas>
       <script>
           const video = document.createElement('video');
           const canvasElement = document.getElementById('canvas');
           const canvas = canvasElement.getContext('2d');
           const loading = document.getElementById('loading');
           let isReadQR = false;
       
           //QRコードを書く
           $('#qrcode').qrcode({width: 64, height: 64, text: "information"});
           $('#qrinput').on('blur',function(){     //フォーカスが外れた時に入力内容でQRコードを書く
               $('#qrcode').html('');
               $('#qrcode').qrcode({width: 64, height: 64, text: $('#qrinput').val()});
           });
           $('#qrON').on('click',function(){       //ボタンクリックにてQRコードリーダーを起動する
               qrRead();
           });
           //QRコードを読む
           function qrRead() {
               isReadQR = false;
               navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
               .then((stream) => {
                   video.srcObject = stream;
                   video.setAttribute('playsinline', true);
                   video.play();
                   requestAnimationFrame(tick);
               });
           }
           
           function tick() {
             loading.textContent = 'ロード中...';
             if (video.readyState === video.HAVE_ENOUGH_DATA) {
               loading.hidden = true;
               canvasElement.hidden = false;
               canvasElement.height = video.videoHeight;
               canvasElement.width = video.videoWidth;
               canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
               var imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
               var code = jsQR(imageData.data, imageData.width, imageData.height, {
                 inversionAttempts: 'dontInvert',
               });
               if (code && !isReadQR) {
                   isReadQR = true;
                   $('#qrinput').val(code.data);       //読み込んだQRコードをtextareaにセットする
                   $('#qrinput').focus();
                   $('#qrinput').blur();
               }
             }
             if(!isReadQR){
               requestAnimationFrame(tick);
             }
           }
       </script>
   </body>
</html>

wslのvimでクリップボードを書いたり読んだり

以前、「WSL2のvimでクリップボードを使う」でクリップボードを使えるvimとVcXsrvをインストールする方法を紹介したが、何もインストールすることなくwindows標準のコマンドだけで行う方法を紹介します。

クリックボードに書き込む

  • clip.exe
[.vimrc]
augroup myYank
    autocmd!
    autocmd TextYankPost * :call system('clip.exe', @")
augroup END

グループを登録(augroup myYank)しグループ内のコマンドをクリア(autocmd!)しヤンクしたテキストをクリップボードにコピーするコマンド(autocmd TextYankPost * :call system('clip.exe', @"))を追加する。

クリップボードを読む

[.vimrc]
command! CV :r! powershell.exe -command "get-clipboard"

powershellクリップボードを読み出し挿入(:r!)するコマンドを追加(command! CV )する。コマンド':CV'でクリップボードの内容をカーソル位置に追加する。

ブラウザでQRコードを読み取る

ブラウザでQRコードを読み取る

ブラウザからカメラを起動してQRコードを読み込めるようにするJavaScriptライブラリjsQRを使用しQRコードを読み込む。

参照:1分でできるjsQRによるブラウザのQRコード読み込みアクセス

ソース

サンプル

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="robots" content="none">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<title>jsQRによるブラウザのQRコード読み込み</title>
<style>
body {
  max-width: 800px;
  margin: auto;
  padding: 1rem;
  font-size: 14px;
  text-align: center;
}
</style>
</head>
<body>
<h1>jsQRによるブラウザの<br>QRコード読み込みサンプル</h1>
<p>QRコードをカメラで読み込むとアクセスできます。</p>
<div id="loading">ブラウザのカメラの使用を許可してください。</div>
<div id="message">QRコードを読み込んで下さい。</div>
<canvas id="canvas" hidden></canvas>
<script src="https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js"></script>
<script>
const video = document.createElement('video');
const canvasElement = document.getElementById('canvas');
const canvas = canvasElement.getContext('2d');
const loading = document.getElementById('loading');
let isReadQR = false;

navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })                                                                                  .then((stream) => {
    video.srcObject = stream;
    video.setAttribute('playsinline', true);
    video.play();
    requestAnimationFrame(tick);
  });

function tick() {
  loading.textContent = 'ロード中...';
  if (video.readyState === video.HAVE_ENOUGH_DATA) {
    loading.hidden = true;
    canvasElement.hidden = false;
    canvasElement.height = video.videoHeight;
    canvasElement.width = video.videoWidth;
    canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
    var imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
    var code = jsQR(imageData.data, imageData.width, imageData.height, {
      inversionAttempts: 'dontInvert',
    });
    if (code && !isReadQR) {
        isReadQR = true;
        document.getElementById('message').innerHTML = code.data;
    }
  }
  if(!isReadQR){
    requestAnimationFrame(tick);
  }else{
    setTimeout(function() {
          location.href = code.data;
      },1000);
  }
}
</script>
</body>
</html>                                                                                                                                                     
 

レスポンシブデザイン

レスポンシブデザインとは

レスポンシブデザインとは、Webサイトのデザインを「閲覧ユーザーが使用するデバイスの画面サイズに応じて表示を最適化するデザイン」を指します。

メニュー修正

tableタグで横並びのデザインをしていたが、divタグにて横並びにした。

  • display:flex;を使ってdiv要素を横並びにする。
    • divはブロック要素であり、ブロック要素は縦に並びます。div要素を横並びにする為にdisplay:flexをしようする。
  • flex-wrap: wrapで改行を可能にする。
    • flexはデフォルトではnowrapで改行を禁止しています。flex-wrap: wrapで改行を可能にします。画面サイズに合わせて改行するので画面サイズを気にせずデザインできます。

diff

Index: public/css/default.css
===================================================================
--- public/css/default.css (revision 516)
+++ public/css/default.css (working copy)
@@ -271,3 +271,10 @@
 .fixed02{
   z-index: 1;
 }
+.flex{
+    display: flex;
+    flex-wrap: wrap;
+}
+.menucel{
+    width: 20em;
+}
Index: templates/menu/menu.html.ep
===================================================================
--- templates/menu/menu.html.ep    (revision 509)
+++ templates/menu/menu.html.ep    (working copy)
@@ -1,7 +1,8 @@
 % layout 'default';
 % title 'menu' ;
 %== $self->make_panel();
-<table><tr><td style="vertical-align: top;">
+<div class="flex">
+ <div class="menucel">
 %   for my $r (@$_data){
 %       if ($r->{menukbn} =~ /^(H\d)/i){
             %== tag($1,$r->{meisyo});
@@ -14,7 +15,8 @@
             %== "<a href=$r->{URL}$r->{PARAM}>$r->{meisyo}</a><br>"
 %       }
 %   }
-</td></tr></table>
+ </div>
+</div>
 <%
 sub tag{
     my ($tag,$name) = @_;

スワイプしてカレンダーを切り替える

スケジュール帳

スケジュール帳のカレンダーを表示しているとスワイプで月を切り替えたくなる。スケジュール帳に実装してみた。タッチ操作のできる端末かブラウザのシミュレーターでアクセスしてくみてください。(ログインIDをお持ちでない方はそのままGUESTでログインしてくださね)

スケジュールカレンダーをフリックして月を切り替える

タッチイベント

  • touchstart
    • タッチ面に指が触れた時
  • touchmove
    • タッチしながら指を移動させた時
  • touchend
    • タッチしていた指を離した時

javascript(jQuery)

       $(function flickSet() {
           // touchstart touchmove touchendのイベントハンドラを登録
           $('.flick').bind("touchstart touchmove touchend",touchHandler);
           function touchHandler(e){
               e.preventDefault();                       // デフォルトの動作をキャンセルする
               var touch = e.originalEvent.touches[0];   // イベントオブジェクトの取得
               if(e.type == "touchstart"){               // 画面に触れたときの x を取得
                   startX = touch.pageX;
               }else if(e.type == "touchmove"){          // タッチしながら移動した距離を取得
                   diffX = touch.pageX - startX;
               }else if(e.type == "touchend"){           // 離した時
                   if(diffX > 50){                       //   左から右へスワイプした時
                       $("#prevMon").click();            //     前月ボタンをクリックする
                   }
                   if(diffX < -50){                      //   右から左にスワイプした時
                       $("#nextMon").click();            //     次月ボタンをクリックする
                   }
               }
           }
       });