WEBフォントで外字をHTML表示する方法

JavaScript

外字をWEB画面表示する要件が存在するシステム開発は、頻繁ではないですが時より発生します。
筆者の肌感覚としては、官公庁案件に多い気がしています。


その場合、外字をWEBフォントとしてシステムに登録しておく方法が一般的だと思います。
今回は、WEBフォントを使って外字をHTML表示する方法を紹介します。


流れとしては以下になります。
「TTEファイルをWOFFファイルに変換」→「外字のコードを確認」→「font-familyを作成」→「HTML表示」


TTEファイルをWOFFファイルに変換


一般的に、外字フォントはTTEファイル形式で受領します。
TTEファイルをHTMLでも使用できる形式であるWOFFファイルに変換します。
WOFFファイルは「Web Open Font Format」の略です。


変換はツールを使用した方がよいです。
「WOFFコンバート」がシンプルで使いやすいかと思います。


変換する際、「サンプルHTMLファイルを作成する」チェックを付けておくと、あとのHTML表示での確認が楽なのでチェックしておきましょう。


出力するWOFFファイルは、わかり易く「gaiji.woff」としておきます。


外字のコードを確認する


外字で使用するコードを確認する。
こちらもツールを使用した方がよいでしょう。
「FontForge」を使用します。


画面をひらくと、設定されている文字の一覧が表示されます。
定義しているグリフィスのみを確認するためには「エンコーディング」→「Compact」を選択します。

font-familyを作成


HTMLに外字を表示するためには、CSSにWOFFファイルを作成するためのフォント指定をおこなう必要があります。
CSSとしては以下になります。
以下のコードはWOFFファイルに変換で出力したHTMLファイルに記載されております。


「font-face」で「gaiji.woff」を使用したフォントを定義し、「myFontClass」の使用箇所に外字表示が適用されます。


HTML表示


HTMLに外字を表示してみます。
「FontForge」で、unicodeで表現されている外字の文字コードを確認します。
左メニューの下に表示されています。


HTML上で確認するために、FontForgeで確認したunicodeを16進数表現でHTML表示します。


サンプル文字列は「※ここにunicode16進数を記述」です。


“myFontClass”クラスだけではなく、画面全体に外字表示をおこなうためには、body・html の初期化で外字フォントを指定します。
一応、外字フォントを読み込めなかった場合の考慮もおこなっておいた方がよいでしょう。

/* Webフォント指定 */
@font-face {
  font-family: "Gaiji";
  src: url("gaiji.woff")  format('woff');
}

/* 初期化 */
body, html{
    font-family: "Gaiji", "メイリオ", Meiryo, "Noto Sans JP";
}

mapBoxでポリゴン表示。geoJsonの表示内容について変更する。

MapBox

mapBoxでは、地図上に様々なメッシュの表示をおこなうことができます。
今回は、mapBoxを使ってgeoJsonの表示をおこない、かつ、表示内容をパラメータで変更する方法について紹介していきます。


環境情報


  • ブラウザ:Chrome
  • Mapbox:v2.3.1

ポリゴンの表示


以下のHTMLを記載するだけで地図上にポリゴンが表示されます。
とはいっても、mapインスタンスの作成は記載を省略しています。


map.on('load', function () {
    map.addSource('POLYGON_TEST', {
        'type': 'geojson',
        'data': {
            'type': 'FeatureCollection',
            'features': [
                {"type": "Feature", "geometry": {"type": "Polygon","coordinates": [[[139.74609375, 35.70556640625],[139.757080078125, 35.70556640625],[139.757080078125, 35.716552734375],[139.74609375, 35.716552734375],[139.74609375, 35.70556640625]]]}},
            ]
        }
    });
    
    map.addLayer({
        'id': 'PLOLYGON_TEST_fill',
        'type': 'fill',
        'source': 'POLYGON_TEST',
        'paint': {
            'fill-color': '#FFFF00',
            'fill-opacity': 0.1
        },
        'minzoom': 1,
        'maxzoom': 22
    });

    map.addLayer({
        'id': 'PLOLYGON_TEST_LINE',
        'type': 'line',
        'source': 'POLYGON_TEST',
        'paint': {
            'line-color': '#0000FF',
            'line-width': 2
        },
        'minzoom': 1,
        'maxzoom': 22
    });
});

「map.addSource」クラスで、geoJsonで表示する座標情報を定義しています。


ポリゴンの表示内容


ポリゴンの表示内容は、fill(塗りつぶし)とline(線)の定義でおこなうことができます。
パラメータとして準備されているのは、以下となります。


■fill(塗りつぶし)

fill-color

塗りつぶしの色

fill-opacity

不透明度(1が最も透明度が高い)

minzoon

表示する最小のズームレベル

maxzoon

表示する最大のズームレベル


■line(線)

line-color

線の色

line-width

線の太さ

minzoon

表示する最小のズームレベル

maxzoon

表示する最大のズームレベル



Mapboxのスタイルを変更する。日本語の地図表示に変更。

MapBox

WEBアプリケーションを使用しての地図表示で、一番使い勝手がよい(メジャーな)のはGoogleMapかと思います。
しかし、Mapboxも非常に使い勝手がよく、地図表示においてGoogleMapと遜色がない機能を備えてあります。


今回は、Mapboxを使って地図表示を行う上での重要なポイントである、地図スタイルの変更について方法を紹介していきます。


環境情報


  • ブラウザ:Google Chrome
  • Mapbox:2.3.1

スタイルの取得


Mapboxのダッシュボード画面から、「mapBoxStudio」に移動します。

Mapboxに移動する

スタイルの検索で、”Japan”を入力して検索します。
“Mapbox Japan”が表示されますので、クリックしてスタイル編集画面に遷移します。

Mapboxのスタイル検索

スタイル編集画面の右上の「共有」ボタンを押下して、共通ウィンドウを表示します。

Mapboxのスタイル共有

共有ウィンドウで「スタイル URL」をコピーします。
このURLをMapboxのAPIに組み込みをおこないます。

MapboxのURL取得

APIへの組み込み


「スタイル URL」を、MapboxのAPIに設定します。


JavaScriptの、「mapboxgl.Map」インスタンス作成時のパラメータに『style』がありますが、このパラメータをコピーしたURLに変更します。


var map = new mapboxgl.Map({
    container: 'map',
    center: [139.7671563757408, 35.69760688745724],
    zoom: 13,
    style: '※コピーしたURL'
});

では地図表示をおこなってみましょう。
地図表示が、日本語表示となっています。

Mapboxでの地図表示


CSSだけで画像っぽい表示をやってみる。画像は使わない!

CSS

WEBページを作成していく上で、ちょっとした画像を使用したい場合があります。

ひと昔まえであれば、本当にいちいち画像を作成する必要がありましたが、HTML5・CSS3が主流の現在においては、ちょっとした画像は準備する必要はありません。

CSSを使えば、画像を作成しなくても画像っぽい表現が可能となります。


今回は、簡単な例ですが、WEBページ上で”画像っぽい”表示をおこなう方法を紹介します。


環境情報


  • ブラウザ:Chrome81

WEB画面にマークを付ける


例として、一覧画面上に新着の記事については新着であるマークをつける場合を考えます。

よくあるパターンですよね。

恰好良いマークをつけたいのでデザイナーさんに頼んで画像をつくってもらいたいところですが、そんな必要はありません。


以下のような表示であれば、わざわざ画像を作る必要はなく、HTMLとCSSで表現できます。


::after疑似要素を使用した新着マークの表示サンプル

実際のWEBページはこちら


::after疑似要素を使ったサンプルコード


実際は、CSSの::after疑似要素を使ってマーク表示をおこなっています。
::after疑似要素は、選択した要素の最後の子要素として擬似要素を作成します。
よく content プロパティを使用して、要素に装飾的な内容を追加するために用いられます。


まずは、HTMLのサンプルです。

マークを付けたい要素に対して「newクラス」を付加します。

    <table>
        <tr>
            <th>No</th>
            <th>タイトル</th>
            <th>日時</th>
        </tr>
        <tr>
            <td class="new">1</td>
            <td>画像を使わずに画像っぽい表示をさせる①</td>
            <td>2020/06/14 11:27</td>
        </tr>
        <tr>
            <td>2</td>
            <td>画像を使わずに画像っぽい表示をさせる②</td>
            <td>2020/06/13 23:05</td>
        </tr>
        <tr>
            <td>3</td>
            <td>画像を使わずに画像っぽい表示をさせる③</td>
            <td>2020/05/03 08:11</td>
        </tr>
    </table>

次に、CSSのサンプルです。

一応、サンプルWEBページに使用しているCSSを全て紹介していますが、実際にマーク表示で使用している箇所は、「::after」属性部分のみとなります。

        body {
        }
        table, tr, th, td {
            border: solid 1px gray;
        }
        table {
            width: 800px;
        }
        table tr th:nth-child(1) {
            font-weight:bold;
            width:10%;
            background:#FFFFCC;
        }
        table tr th:nth-child(2) {
            font-weight:bold;
            width:60%;
            background:#FFFFCC;
        }
        table tr th:nth-child(3) {
            font-weight:bold;
            width:30%;
            background:#FFFFCC;
        }
        .new::after {
            content:"新";
            font-weight:bold;
            background:#FF0000;
            height:30px;
            width:30px;
            border-radius:21px;
            text-align:center;
            line-height:30px;
            display:inline-block; 
            color:#FFF;
            margin-left:20px;
        }

::after疑似要素の使い方


サンプルを例にして、::after疑似要素の使い方について図で説明します。
あまり難しいものではないです。


CSSでのマーク表示方法

「border-radius」で丸みを表現して画像っぽいスタイルを作成するところがポイントですね。


まとめ


HTMLとCSSだけで、ひとむかし前だと画像を準備する必要があったようなデザインも表現できることが解っていただけたかと思います。


まとめ
  • 指定要素の後に別要素を付加するのは::after疑似要素を使えばよい
  • ちょっとした画像っぽい表現は、HTMLとCSSで可能

それではまた。



JavaScriptで型を意識してコーディング。暗黙的型変換と明示的変換。

Javascript

JavaScriptはスクリプト言語で、暗黙的型変換をおこなってくれるプログラミング言語になります。
暗黙的型変換は便利ですが、思いもよらぬバグを作りこむことがあります。


本記事では、筆者が暗黙的型変換でハマったバグについて紹介し、正解となるプログラミングについて説明していきます。


暗黙的型変換とは


そもそも、暗黙的型変換とはいったいどういう変換なのでしょうか?


JavaScriptの型変換には、暗黙的変換明示的変換の2つがあります。

暗黙的変換とは、”=”で連結された値の中で、どちらかの値の型に合わせる形で変換がおこなわれます。

var num = '1';
var value = num;

この時、変数valueはString型の”1″が格納されます。


しかし、この暗黙的型変換は、しばしば直感的には解りにくい型変換をおこない、非常に解りにくいバグを作りこむことがあります。
プログラマーとしては便利な仕組みなのですが、注意が必要です。


明示的変換とは、プログラムの中で型変換処理を記載して変数宣言する方法です。


var num = Number('1');
var value = num;

この時、valueはNumber型の”1″が格納されます。


型変換をおこなう代表的な関数


暗黙的型変換は、便利な反面、非常に解りにくいバグを作りこむことがあります。
可能な限り、型を意識してプログラミングをしようとした場合に、型変換をおこなう関数を使用することになります。

型変換をおこなってくれる代表的な関数を紹介していきます。


Number(数値に変換)


「Number」は、文字列を数値に変換する関数です。


var num = Number('12345');
var value = num;

valueは数値の12345になります。


parseInt(基数を指定して数値に変換)


「parseInt」は、「Number」と同様に、文字列を数値に変換する関数です。
「Number」との違いは、基数を設定できる点です。


var num = parseInt('12345', 10);
var value = num;

valueは数値の12345になります。
10は10進数を指定しています。


var num = parseInt('A', 16);
var value = num;

この場合は16進数での変換となるので、valueは10です。


String(文字列に変換)


「Number」は、数値を文字列に変換する関数です。


var num = String('12345');
var value = num;

valueは文字列の12345になります。


暗黙的変換が作りこむバグ


型を意識せずにプログラミングした結果、筆者が作りこんでしてしまったバグの例を紹介します。

以下、サンプルプログラムです。


// 開始Idxと終了Idxを取得
var startIdx = document.getElementById("startIdx").value;
var endIdx = document.getElementById("endIdx").value;

// 取得数分ループ
for (var lc = startIdx; lc < endIdx; lc++) {
    console.log("lc=" + lc);
}

startIdxと1、endIdxが10の結果は以下です。
正解です。

lc=1
lc=2
lc=3
lc=4
lc=5
lc=6
lc=7
lc=8
lc=9
lc=10

startIdxと101、endIdxが110の結果は以下です。
これも正解です。

lc=101
lc=102
lc=103
lc=104
lc=105
lc=106
lc=107
lc=108
lc=109
lc=110

startIdxと91、endIdxが100の結果はどうでしょう?
何も表示されません。
つまり、ループに入らないです。


91の文字列を100の文字列でループしてしまっているため、文字コードとしては91より100の方が小さいために、このバグが発生します。
「document.getElementById()」は、HTML内にある値を取得する関数ですが、この際、文字列として数値を取得します。
正解のプログラムとしては以下になります。


// 開始Idxと終了Idxを取得
var startIdx = documentGetelementId("startIdx");
var endIdx = documentGetelementId("enddx");

// 数値に変換
startIdx = Number(startIdx);
endIdx = Number(endIdx);

// 取得数分ループ
for (var lc = startIdx; lc < endIdx; lc++) {
    console.log("lc=" + lc);
}

for文のループは数値全体の処理になっているので、開始位置と終了位置は、いったん数値に変換するのが正解、ということになります。
数値変換処理をおこなうようにして修正したプログラムの実行結果は、startIdxと91、endIdxが100の場合は以下結果になります。
正解の結果ですね。


lc=91
lc=92
lc=93
lc=94
lc=95
lc=96
lc=97
lc=98
lc=99
lc=100

まとめ


暗黙的型変換は便利ですが、思いもよらぬバグを作りこむ要因をはらんでいます。
場面によって、きちんと型変換をおこなってプログラミングするようにしましょう。



Windows環境でNode.JSとPostgreSQLを接続してクエリ発行


前回、Windows上にNode.jsの環境を構築して、Hello,Worldを出力されるところまでおこないました。



今回は、Node.jsとPostgreSQLを接続して、データベースに格納されているデータをブラウザ上に表示させるところまでおこないたいと思います。


やっぱり、データベースに接続してデータを表示するというところまでは、お勉強としておさえておきたいところです。


環境情報


  • OS:Windows10
  • Webサーバ:Node.js 12.16.3
  • DB:PostgreSQL9.6

PostgreSQLとは


PostgreSQL(ぽすとぐれすきゅーえる)は、オープンソースのデータベースになります。
よく、「ぽすぐれ」と言われています。


PostgreSQLはオープンソースなので、気軽に使えるのが良いところです。
かつ、標準SQL にならった実装になっていますので、標準SQLでほぼ全てのクエリを実行することができます。


この記事では、PostgreSQLのダウンロードと環境構築の紹介は省略します。


node-postgres


Node.jsでPostgreSQLと接続をおこなうためには、「node-postgres」を使用する必要があります。
「node-postgres」は、npmでインストールをおこなうことができます。

任意のフォルダを作成して、そのフォルダで以下のコマンドを実行します。


npm install --save pg

インストールが完了すると、インストールしたフォルダに「node_modules」が作成され、インストールが完了します。
このフォルダにプログラムを作成していきます。


PostgreSQLに接続してデータ表示


実際にNode.jsのプログラムを作成して動かしてみます。
データベースにはあらかじめて、以下のデータを格納しておきます。

person_id

name

kana

gender

1

山田太郎

やまだたろう

1

2

山田次郎

やまだじろう

1

3

山田三郎

やまださぶろう

2


上記のデータをクエリで取得し、ブラウザ上に表示するプログラムを作成します。
プログラムとしては以下になります。


// モジュールを準備
var http = require('http')
var {Client} = require('pg'); 

http.createServer(function (req, res) {

    // PostgreSQLに接続
    var client = new Client({
        user: 'postgres',
        host: 'localhost',
        database: 'nodeJsDB',
        password: 'postgres',
        port: 5432
    })
    client.connect()

    // HTTPレスポンスヘッダを出力
    res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'})

    // クエリを実行してTABLEタグで出力
    var query = client.query(
        "select person_id, name, kana, gender from persons;",
         function(err, result) {
        res.write('<html><head></head><body><table>');
        for(lc = 0; lc < result.rows.length; lc++){
            res.write('<tr>');
            res.write("<td>"+result.rows[lc].person_id+"</td>" ); 
            res.write("<td>"+result.rows[lc].name+"</td>" ); 
            res.write("<td>"+result.rows[lc].kana+"</td>" ); 
            res.write("<td>"+result.rows[lc].gender+"</td>" ); 
            res.write('</tr>');
        }
        res.end('</table></body></html>')
    });
}).listen(8989)

プログラムとしては簡単です。
PostgreSQLに接続してクエリを実行し、実行結果をTABLEタグに出力するのみです。
nodeコマンドでNode.jsのサーバを起動します。


node pgConnect.js

URLにアクセスすると実行結果が表示されます。

http://localhost:8989/pgConnect

Node.jsの実行結果

まとめ


いかがでしょうか?
PostgreSQLであっても、Node.jsから簡単に接続がおこなうことができました。

本当はMongoDBとか使ってみたいんですが、しばらくはPostgreSQLでNode.jsの勉強を進めようと思います。



WindowsにNode.jsの環境を構築する-サンプルプログラム実行まで


最近、業務でNode.jsを使ったプロジェクトが増えてきたように思います。
筆者は業務アプリケーションの開発をおこなうSIerなので、実態としては業務アプリケーションではJavaや.NETが主流です。


とはいっても、ポツリポツリと、Node.jsを使ったプロジェクトも出てきています。
時代遅れにならないように、個人的に勉強を始めようかとおもい、まずは環境構築からはじめてみます。


という訳で今回は、Node.jsのダウンロードと環境構築、および、サンプルプログラムを実行するまでを紹介します。


環境情報


  • OS:Windows10
  • Webサーバ:Node.js 12.16.3

Node.jsのダウンロードとインストール


Node.jsは、以下の公式サイトからダウンロードできます。


Node.js
 
Node.js
https://nodejs.org/ja/
Node.js ブログ: リリース

2020/5/3現在では、インストーラはLTS版と最新版の2つがあります。
LTS版とは「Long term support版」の略でして、サポート期間が長く、そのサポート期間の間はバグの修正や主要な機能の保証がされているバージョンのことです。


何かしら最新版を使用しないといけない事情がない限りは、LTS版をダウンロードすることをお勧めします。

という訳で、今回はLTS版をダウンロードします。


「node-v12.16.3-x64.msi」というファイルをダウンロードしたら、そのファイルをダブルクリックしてインストールを開始します。
インストール自体は、ウィザードに沿ってインストールをおこなっていけば、簡単に終了しました。


インストールが完了したら、インストール完了後の確認をおこないます。
インストールが完了すると、Windowsのプログラムメニューに「Node.js command pronpt」というメニューが増えているかと思います。
そのメニューをクリックします。

Node.jsのコマンドプロンプト

コマンドプロンプトがひらきます。
Node.jsのインストールバージョンを確認するために、以下のコマンドを実行します。

node --version

インストールされたNode.jsのバージョンが表示されれば、無事にインストール完了です。


JSファイル単独で実行


JSファイルを作成してコマンドプロンプトで実行してみます。
「helloWorld.js」というサンプルプログラムを作成して実行します。


「helloWorld.js」の中身は、”Hello,World”をコンソールログで出力するだけです。

console.log('Hello, World')

コマンドプロンプトで、nodeコマンドを使用して実行します。

D:\>node helloWorld.js
Hello, World

Webサーバで実行


次は、Webサーバを起動してブラウザ上で”Hello,World”を表示します。
「helloWorldServer.js」というサンプルプログラムを作成します。

こちらも同様に、”Hello,World”を標準出力するだけです。

var http = require('http')

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'})
    res.end(`Hello World \n`)
}).listen(8989)

コマンドプロンプトでWebサーバを起動します。

D:\>node helloWorldServer.js

コマンドを実行した後に、ブラウザで以下のURLにアクセスします。

http://localhost:8989/helloWorldServer

ブラウザ上に”Hello,World”が表示されました。

Node.jsのWebサーバでHelloWorld

まとめ


いかがでしょうか?
簡単に”Hello,World”が表示できました。


開発環境はできたので、これをベースにいろいろ勉強していきたいと思います。



canvasタグを使ってブラウザ上でお絵描きアプリを作る

JavaScript


ブラウザ上でのお絵描きは、HTML5の<canvas>タグを使って描画エリアを準備し、マウス操作をJavaScriptで制御をおこなうことで可能になります。


今回は、canvasタグを使ってブラウザ上でお絵描きをおこなう方法を紹介します。

JavaScriptでマウスの動きを制御して、canvasタグ上にお絵描きをおこないます。


HTMLとJavaScriptだけで、機能を実現することができます。


環境情報


  • ブラウザ:Chrome81
  • JQuery:JQuery2.2.4

サンプルプログラム


早速ですが、サンプルプログラムを紹介します。

紹介しているHTMLとJavaScriptをそのままコピペして使って頂ければ、基本的な機能をそなえたお絵描きアプリがブラウザ上で実現できます。


サンプルプログラムで動作するお絵描きアプリは、以下のURLから起動できます。

さくさく TECH
お絵描きアプリケーション
https://sakusaku-techs.com/sample/draw/
お絵描きアプリケーションのサンプルです。簡単にブラウザ上でお絵描きができます。undo・redoも可能です。

HTMLとJavaScriptは以下になります。


  • HTML
<body>
    <div>
        <canvas id="canvas" style="border:1px solid gray;"></canvas>
    </div>
    <div>
        <input type="button" id="undo" name="undo" value="undo">
        <input type="button" id="redo" name="redo" value="redo">
    </div>
</body>

  • JavaScript
//
// JavaScriptのグローバル変数群
//
var CANVAS_SIZE;
var undoDataStack = [];
var redoDataStack = [];
var mouseDown = false;

$(function() {
    //
    // 画面読み込み時のロード処理
    //
    $(document).ready(function(){

        // キャンバスのサイズを設定
        $('#canvas').css('width', '600px');
        $('#canvas').css('height', '600px');

        // キャンバスの属性を設定
        canvas = document.getElementById('canvas');
        canvas.width = 600;
        canvas.height = 600;
        CANVAS_SIZE = canvas.clientWidth;

        // 描画開始 → 描画中 → 描画終了
        canvas.addEventListener('mousedown', startDraw, false);
        canvas.addEventListener('mousemove', drawing, false);
        canvas.addEventListener('mouseup', endDraw, false);
    });

    //
    // undo
    //
    $("#undo").click(function() {

        if (undoDataStack.length <= 0) {
            return;
        }

        canvas = document.getElementById('canvas');
        context = canvas.getContext('2d');
        redoDataStack.unshift(context.getImageData(0, 0, canvas.width, canvas.height));

        var imageData = undoDataStack.shift();
        context.putImageData(imageData, 0, 0);
    });

    //
    // redo
    //
    $("#redo").click(function() {

        if (redoDataStack.length <= 0) {
            return;
        }

        canvas = document.getElementById('canvas');
        context = canvas.getContext('2d');
        undoDataStack.unshift(context.getImageData(0, 0, canvas.width, canvas.height));

        var imageData = redoDataStack.shift();
        context.putImageData(imageData, 0, 0);
    });
});

//
// 描画開始
//
function startDraw(event){

    // 描画前処理をおこないマウス押下状態にする。
    beforeDraw();
    mouseDown = true;

    // クライアント領域からマウス開始位置座標を取得
    wbound = event.target.getBoundingClientRect() ;
    stX = event.clientX - wbound.left;
    stY = event.clientY - wbound.top;

    // キャンバス情報を取得
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");
}

//
// 描画前処理
//
function beforeDraw() {

    // undo領域に描画情報を格納
    redoDataStack = [];
    canvas = document.getElementById('canvas');
    context = canvas.getContext('2d');
    undoDataStack.unshift(context.getImageData(0, 0, canvas.width, canvas.height));
}

//
// 描画中処理
//
function drawing(event){

    // マウスボタンが押されていれば描画中と判断
    if (mouseDown){
        x = event.clientX - wbound.left;
        y = event.clientY - wbound.top;
        draw(x, y);
    }
}

//
// 描画終了
//
function endDraw(event){

    // マウスボタンが押されていれば描画中と判断
    if (mouseDown){
        context.globalCompositeOperation = 'source-over';
        context.setLineDash([]);
        mouseDown = false;
    }
}

//
// 描画
//
function draw(x, y){
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");
    context.beginPath();
    context.strokeStyle = "black";
    context.fillStyle = "black";
    context.lineWidth = 2;
    context.lineCap = "round";

    context.globalCompositeOperation = 'source-over';
    context.moveTo(stX,stY);
    context.lineTo(x,y);
    context.stroke();
    stX = x;
    stY = y;
}

HTMLの構成


HTMLはとてもシンプルです。
HTML5の<canvas>タグを定義しているだけ、です。

<canvas id="canvas" style="border:1px solid gray;"></canvas>

<canvas>タグはHTML5から追加されたHTMLタグになります。
2Dのグラフィックを表示することができるので、HTMLとJavaScriptでゲームやグラフィックデザインをおこなうことができます。


ブラウザ上でのゲームは、ほぼ全てこの技術が使われています。


JavaScriptの構成


ポイントは2つありまして、1点目は描画の基本処理。


描画開始 → 描画中 → 描画終了 の3段階で処理をわけています。
イベントの検知は、JQueryのイベントリスナーを使用しています。


// 描画開始 → 描画中 → 描画終了
canvas.addEventListener('mousedown', startDraw, false);
canvas.addEventListener('mousemove', drawing, false);
canvas.addEventListener('mouseup', endDraw, false);

「mousedown(左クリック開始)」のイベントを「startDraw」ファンクションで処理しています。
クリックした位置を算出し、描画開始を認識します。


「mousemove(マウス移動)」のイベントを「drawing」ファンクションで処理しています。
マウス移動に従って、canvas上に線を描画しています。


「mouseup(左クリック終了)」のイベントを「endDraw」ファンクションで処理しています。
左クリックを終了した位置が描画の終了位置と認識します。


もう一つのポイントとしてはUNDO・REDOです。
UNDOはやり直し、REDOはやり直しのやり直し、です。


仕組みは簡単です。
グローバル変数に「undoDataStack」「redoDataStack」を準備し、この領域にデータを格納することでUNDO・REDOを実現しています。


var undoDataStack = [];
var redoDataStack = [];

描画終了したら「undoDataStack」にデータを格納し、UNDOをやったら「redoDataStack」にデータを格納します。
UNDO・REDOの操作をおこなったら、この「undoDataStack」「redoDataStack」領域からデータを取り出し、画面表示をおこないます。


まとめ


いかがでしたでしょうか?


<canvas>タグを使えば、簡単にブラウザ上でお絵描きができることがわかって頂けたかと思います。
今回は紹介しきれませんでしたが、色の指定や図形の指定もおこなうことができます。
ぜひお試しください。



Chrome81へのバージョンアップでシステム管理者がやるべきこと。混合コンテンツ対応。

JavaScript

こんにちは。
さくさくTECHブロガーの「さく」です。


Chrome81のバージョンアップで、やっかいなバージョンアップがおこなわれます。
「混合コンテンツ」に対するChromeの動作が変更になるようです。


本記事では、Chrome81でエラー扱いとなるパターンの検証をおこないます。


環境情報


  • Chrome: 81.0.4044.83(Official Build)beta (64 ビット)

2020/03/29時点では、Chrome81ベータ版しか手に入りません。
なので、このバージョンで検証してみます。


ちなみに、Chrome81正式版のリリースは延期されているようです。
現時点では、延期したリリース日も未定です。


混合コンテンツとは


まず、混合コンテンツとは何か?という事ですが、簡単に説明すると“https化されたサイト内のhttpコンテンツ”です。


“混合コンテンツ”とは、閲覧ページが安全なHTTPS接続で読み込まれているにもかかわらず、そのHTTPSページに含まれる他のリソース(画像、動画、スタイルシート、スクリプトなど)が暗号化されていない、安全ではないHTTP接続で読み込まれている状態、つまりHTTPSページにHTTPサブリソースが混在している状態をいいます。


httpsで常時接続しているサイトにおいて、サイトの中で読み込まれている「画像」「CSS」「スクリプト」がhttpで接続されている場合に”混合コンテンツ”と判断されます。


何がブロックされるのかを検証


Chrome81では、本当に全てのhttpコンテンツがブロックされるのでしょうか?
検証してみました。


まず、混合コンテンツが発生するテストサイトを作成します。
以下のURLのサイトになります。
JavaScript・CSS・画像の3つについて、httpで読み込みをおこなっています。


さくさく TECH
混合コンテンツのテストサイト
https://sakusaku-techs.com/sample/mixed/mixed.html
JavaScript・CSS・画像、の3つについて、httpで読み込みをおこなっています

HTMLは以下になります。

<!DOCTYPE html>
<head>
  <title>混合コンテンツのテストサイト</title>
  <link rel="stylesheet" href="http://sakusaku-techs.com/sample/mixed/css/base.css" />
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22http%3A%2F%2Fsakusaku-techs.com%2Fsample%2Fmixed%2Fjs%2Fmixed.js%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</head>
<body>

混合コンテンツの試験サイト
<img src="http://sakusaku-techs.com/sample/mixed/image/images.png">
</body>
</html>

Chromeのディベロッパーツールでエラーを確認してみます。
CSSとJavaScriptはエラーが発生していますね。
エラーの内容は「Mixed Contents」です。



  • CSSのエラー
Mixed Content: The page at 'https://sakusaku-techs.com/sample/mixed/mixed.html' was loaded over HTTPS, but requested an insecure stylesheet 'http://sakusaku-techs.com/sample/mixed/css/base.css'. This request has been blocked; the content must be served over HTTPS.

  • JavaScriptのエラー
Mixed Content: The page at 'https://sakusaku-techs.com/sample/mixed/mixed.html' was loaded over HTTPS, but requested an insecure script 'http://sakusaku-techs.com/sample/mixed/js/mixed.js'. This request has been blocked; the content must be served over HTTPS.

かしかし、画像だけはエラーではワーニングになりました。

  • 画像のワーニング
Mixed Content: The page at 'https://sakusaku-techs.com/sample/mixed/mixed.html' was loaded over HTTPS, but requested an insecure image 'http://sakusaku-techs.com/sample/mixed/image/images.png'. This content should also be served over HTTPS.

外部コンテンツの読み込み部分は、CSSとJavaScriptはエラー、画像はワーニングになる、という事がわかりました。
画像はワーニングでブラウザ上に画像が表示されるのですが、これはもしかしたらChrome81のベータ版だからかもしれません

もしかしたら、正式版だとエラーになってしまうかも、です。


HTMLのhttp部分をhttpsに変更すれば、エラーは全て解消されました。


まとめ


混合コンテンツが原因でJavaScriptやCSSの読み込みがエラーとなった場合、そのサイトは”まったく動作しない”という可能性があります。
早急に対処した方がよさそうです。



Web画面での時間入力インターフェース!timedropperを使い倒してみる!

カレンダー

Webシステムの開発をおこなっていく上でよく必要となるのは、”日付入力””時間入力”のインターフェースです。

JavaScript(JQuery)を使って入力インターフェースを作るケースがほとんどかと思います。


メジャーなところでは、「DatePicker」「DateTimePicker」あたりですかね?

DatePicker
DateTimePicker

他にも「Material DatePicker」「pickadate」があり、各々で特徴があります。

しかし、Web画面のデザイン次第ではカレンダー形式ではない日付・時間の入力が必要となる場合があります。


という訳で今回は、「timedropper」を使ってみたいと思います。ちょっと面白いインターフェースです。

また、オプションについて一覧形式でまとまっているサイトがなかったので、まとめてみました。


timedropperを使ってみる

とりあえず動かしちゃいましょう。

サンプルソースコードと、サンプルソースコードで動作するインターフェースは以下になります。


サンプルはこちら



    timedropper
    
    
    


    
    


timedropperのサンプル

おもしろいインターフェースで、アナログ時計の意識したインターフェースになります。


バルーンが、アナログ時計での長針・短針になっています。
時間(Hour)を変更したい場合は時間(Hour)をクリックしてバルーンを動かします。

分(Minutes)も同様です。

timedropperの使い方

timedropperには、いくつかのオプションが用意されています。

解り易いオプションもあれば解り辛いオプションもあるのですが、使用方法含めて紹介していきます。

timedropperの基本的なオプション

まずは基本的なオプションを使ってみます。

色系ですね。

一覧でまとまっているサイトを見つけることができなかったので、まとめてみました。


オプション名

日本語名

デフォルト

説明

primaryColor

主色

#1977CC

バルーンで選択中の時・分の色です。

textColor

文字色

#555

バルーンで選択していない時・分の色です。

backgroundColor

背景色

#FFFFFF

背景は全てこの色になります。

“バルーン部分だけ別の色”というのは、オプションではできないようです。

borderColor

枠線色

#1977CC

枠線は全てこの色になります。

 

 

 

 

 

上記のオプションを実際に設定して動かしてみましょう。

色が自由に設定できるので、印象が違ってきますね。


基本的なオプションを指定したサンプルはこちら




    timedropper
    
    
    


    
    



基本的なオプションを指定したtimedropper

timedropperの応用オプション

色以外のオプションもあります。

あまり豊富ではありませんが、ちょっとしたカスタマイズができます。


オプション名

日本語名

デフォルト

説明

autoswitch

自動補正

false

時・分を切り替えた時に、バーン位置を自動的に選択位置に補正します。

meridians

12時間表記

false

24時間表記ではなく、12時間表記にします。

時計部分に、「AM」「PM」が表示されます。

format

時間のフォーマット

h:mm a

選択した時刻の表示フォーマット。

mousewheel

マウスホイールによる変更

false

マウスホイールによる変更を許可します。

init_animation

初期表示時のアニメーション

fadein

dropdown:上から下にフェードイン

※他にあるんですかね?すいません。見つけきれませんでした。。。

setCurrentTime

現在時刻の設定

true

デフォルトで現在時刻を設定するか。


上記のオプションを設定してみます。

formatは助かりますね。

よく使うと思います。

応用オプションを指定したサンプルはこちら




    timedropper
    
    
    


    
    




timedropperの応用オプション設定

まとめ

いかがでしたでしょうか?

timedropperのオプションは全て網羅しているかと思います。

もし、timedropperを使うことがあった場合は、ぜひ参考にして頂ければと思います。