水準器アプリの試作1
Contents
スマートフォンからGoogle 検索で「水準器」と検索すると、検索最上位にWebアプリ「水準器」が表示されます。
このWebアプリは、検索画面上で既に動作していて、スマートフォンをテーブルに置くと、テーブルの傾きが計測できます。
今回、このような「水準器」を試作してみました。
試作した「水準器」アプリは、大きく2つの機能で構成されています。
先ず、加速度センサーの値から、スマホの傾斜(方向、大きさ)を計算する、計算機能。
次に、計算結果をビジュアル表示する、表示機能です。
- 計算機能:加速度センサー計算
- 表示機能:スマホ傾斜表示
本記事「水準器アプリの制作1」で、「表示機能」について説明します。
次回の「水準器アプリの制作2」で、「計算機能」について説明します。
水準器アプリの画面
Fig.1 は、スマートフォンの画面を正面からみた図です。

ウィンドウ(Window)上にCanvas があります。
Canvas の幅と高さは次のコマンドで、Windowの幅と高さに合わせています。
canvas.setAttribute(“width”, window.innerWidth); canvas.setAttribute(“height”, window.innerHeight);
window.innerWidth はWindow の幅、window.innerHeight はWindow の高さです(Fig.1 参照)。
そのため、Canvas 座標系は、Window 座標系と完全一致しています(Fig.1 参照)。
- Canvas 座標系: Window 座標系と一致
Canvas 座標系
Canvas 座標の原点(点O)は、Window の左上端の点です。
その点から、右方向にi 軸、下方向にj 軸が伸びています(Fig.1 参照)。
Canvas の中心(点C)
Canvas の中心座標(点Cの座標)は、以下の式で計算します。
C[0] = i0; C[1] = j0;
ここで、C[0] は点C のi 座標、C[1] は点C のj 座標です。
i0, j0 は、Window の中心座標で、以下で与えられます。
i0 = window.innerWidth / 2; j0 = window.innerHeight /2;
正方形(Square)
Canvas 上に、正方形(Square)があります。
正方形の位置とサイズは、以下となります。
- 位 置: Canvas の中心
- サイズ: 一辺が edge length の長さ
正方形の左上に点S があります。
正方形は、グラデーションにより、スマートフォンの傾き方向を表示します。
Fig.1 では、スマートフォンが「右」方向に傾いていることを「表示」しています。
水準器アプリの表示機能
水準器アプリでは、スマートフォンの傾斜(方向、大きさ)を表示します。
正方形(Square)
Fig.2 は、Fig.1 中の正方形(Square)を拡大したものです。

Fig.2 は、傾斜の方向を表示する機能の説明図です。
- 傾斜の方向は、グラデーションで表現します
Fig.2 左側は、グラデーション表示の説明図です。
Fig.2 右側は、グラデーション表示の結果です。
正方形のグラデーション表示(例. 左側:白、右側:黒)で、「右方向に傾いている」ことを表しています。
また、正方形の中心に点Cがあります。
正方形上の点Sの座標は、以下となります。
S[0] = C[0] - edgLen / 2; S[1] = C[1] - edgLen / 2;
ここで、S[0] は点S のi 座標、S[1] は点S のj 座標です。
変数「edgLen」には、正方形の一辺の長さ(Edge length)が代入されています。
グラデーション表示
円
Fig.2 左側、正方形に内接する「円」があります。
点Pと点Qが常に円上にあり、それらは点Cをはさんで対称な位置にあります。
点P・点Qは、スマートフォンの傾き方向が変化することで、円上を移動します。
- 点P・点Qは、円上を動く
傾きの方向
傾きの方向は、加速度センサーの出力から計算します。
「点Cから点Pの方向」に傾いているとして計算し、計算結果は、点Pの円上での位置情報となります。
- 傾きの方向: 点Cから点Pへの方向
グラデーション
点Pと点Qに異なる「色」を指定し、正方形をグラデーション色で描画します。
- 点Pの色: 黒
- 点Qの色: 白
プログラム
プログラム1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gradation</title>
<style type="text/css">
* { margin: 0; padding: 0; border: 0; }
</style>
<script>
var canvas;
var ctx;
var i0, j0;
var C = [];
var S = [];
var edgLen = 300; // edge length[pixel]
function drawGradation(P) {
var Q = [];
Q[0] = 2*C[0] - P[0]; // S[0] + (C[0]-S[0]) - (P[0]-C[0])
Q[1] = 2*C[1] - P[1]; // S[1] + (C[1]-S[1]) + (C[1]-P[1])
//
var grad = ctx.createLinearGradient(P[0], P[1], Q[0], Q[1]);
grad.addColorStop(0, "black");
grad.addColorStop(1, "white");
ctx.fillStyle = grad;
//
ctx.fillRect(S[0], S[1], edgLen, edgLen);
ctx.fill();
}
window.onload = function() {
canvas = document.getElementById("canvas");
//
canvas.setAttribute("width", window.innerWidth);
canvas.setAttribute("height", window.innerHeight);
ctx = canvas.getContext("2d");
if (!ctx) return;
//
i0 = window.innerWidth/2;
j0 = window.innerHeight/2;
C[0] = i0;
C[1] = j0;
S[0] = C[0] - edgLen/2;
S[1] = C[1] - edgLen/2;
//
var P = [];
P[0] = S[0] + edgLen; // example
P[1] = S[1] + edgLen/2; //
drawGradation(P);
}
</script>
</head>
<body>
<canvas id="canvas" style="background-color:green;"></canvas>
</body>
</html>
プログラムの解説
グローバル変数
var canvas;
var ctx;
var i0, j0;
var C = [];
var S = [];
var edgLen = 300; // edge length[pixel]
プログラム1 の12 行目では、Window の中心座標を保存する変数(i0, j0)を宣言しています。
13 行目は、点Cの座標を保存するための変数(C)を宣言しています。
14 行目は、点Sの座標を保存するための変数(S)を宣言しています。
15 行目、edgLen は、正方形の一辺の長さを保存する変数で、300(pixel)で初期化しています。
window.onload 関数
window.onload = function() {
canvas = document.getElementById("canvas");
//
canvas.setAttribute("width", window.innerWidth);
canvas.setAttribute("height", window.innerHeight);
ctx = canvas.getContext("2d");
if (!ctx) return;
//
i0 = window.innerWidth/2;
j0 = window.innerHeight/2;
C[0] = i0;
C[1] = j0;
S[0] = C[0] - edgLen/2;
S[1] = C[1] - edgLen/2;
//
var P = [];
P[0] = S[0] + edgLen; // example
P[1] = S[1] + edgLen/2; //
drawGradation(P);
}
プログラム1 の34-35行 で、Canvas の大きさ(横幅、高さ)をWindow の大きさと同じにしています。
39-44 行で、各値(i0, j0, 点C座標, 点S座標)を計算しています。
46-48 行で、点Pの座標値を、一例として、設定しています。
49 行目で、点Pの座標値を実引数として、drawGradation 関数を呼んでいます。
drawGradation 関数
function drawGradation(P) {
var Q = [];
Q[0] = 2*C[0] - P[0]; // S[0] + (C[0]-S[0]) - (P[0]-C[0])
Q[1] = 2*C[1] - P[1]; // S[1] + (C[1]-S[1]) + (C[1]-P[1])
//
var grad = ctx.createLinearGradient(P[0], P[1], Q[0], Q[1]);
grad.addColorStop(0, "black");
grad.addColorStop(1, "white");
ctx.fillStyle = grad;
//
ctx.fillRect(S[0], S[1], edgLen, edgLen);
ctx.fill();
}
プログラム1 の17 行目、drawGradation 関数の仮引数(P)は、点Pの座標が保存されている2 次元配列です。
19-20 行で、点Qの座標を計算しています。
22-25 行で、点Pの座標で「黒」、点Qの座標で「白」となるグラデーションを設定しています。
27 行目で、正方形をグラデーション描画しています。
