とある角度から

お腹いっぱいたべられる幸せ

webフォントの使い方といくつかTips

webフォント関連について纏めてみました。

webフォントの設定方法

webフォントはcssで単に適用することができます。
@font-faceでフォント名と対象フォントファイルへのパスを指定し、font-familyに指定するだけです。
以下、ソースです。

body {
  font-family: 'LogoTypeGothic', 'sans-serif';  // @font-faceで指定した文字列を指定
}

@font-face {
  font-family: 'LogoTypeGothic'; // font-familyで指定する名称
  src: url('/xxx/07LogoTypeGothic7.ttf'); // フォントファイルへのパス
}

※フォントを使用する際は、ライセンスにご注意
webサイトでの利用は、クライアントへフォントをダウンロードすることになるので、フォントの再配布に当たります。

Google Fontsの利用

Google Fontsで公開されているフォントなら、フォントファイルなしで直ぐに適用することができます。

1. 使用したいフォントを選んで、右下のボタン群の真ん中を押します。
f:id:n_1010real:20140422154917p:plain
2. 色々指定をした後、ページ中断以降にあるタグとcssを設定します。
f:id:n_1010real:20140422155102p:plain

↓観づらいのでコピペ(選択内容によって毎回違うのでサイトからコピッてね)

  • head内に以下のタグを追加
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
  • cssで適用したい要素にfont-familyを追加指定
font-family: 'Open Sans Condensed', 'sans-serif';

これで完了です。

和文フォントのモバイルでの利用

和文を含んだフォントファイルはメガを超えるサイズのものが一般的です。
モバイルでの利用を想定すると、ちょっとサイズが気になることも…
そんな場合には、ひらがな・カタカナのみ適用し、漢字はシステムフォントという選択肢もあります。
(うまく合うフォントは限られますが)

方法はごく単純で、漢字を含まないフォントファイルを用意するだけです。
指定されたフォントの中に、該当の文字がなければ、漢字はシステムフォントが適用されます。
で、漢字を含まないフォントファイルの作り方は、以下のサイトを参考にさせて頂きました。

文字を制限した軽量な日本語 Web フォントを作成する方法 - てっく煮ブログ

※フォントから漢字を抜く行為はフォントの改変+再配布となるので、ライセンスにご注意

javascriptでデバイスの向きと加速度を取得

javascriptでデバイスの向きとか加速度を取得してみた。

DeviceOrientation Event Specification
上記ドラフトによると

  • デバイスの向きは、deviceorientationイベントで取得
  • 西向き、画面は上で水平な平面にデバイスを置いた場合の値は、{alpha: 90, beta: 0, gamma: 0}
  • デバイスの加速度は、devicemotionイベントで取得
  • 画面は上で水平な平面にデバイスを置いた場合、加速度はすべてゼロ、重力加速度は{x: 0, y: 0, z: 9.81}
  • 画面はずっと上で向きも変わらずに自由落下した場合、加速度は{x: 0, y: 0, z: -9.81}、重力加速度はすべてゼロ

compass部分は飛ばしました

以下、ソース。
デフォルトだと加速度の桁数がパナいので、小数点以下3桁のみ表示

[javascript]

window.onload = function(){
    // デバイスの向きを取得
    window.addEventListener("deviceorientation", function(e) {
        e.preventDefault();
        document.getElementById("oinfo").innerHTML = "alpha: " + parseInt(e.alpha) + " beta: " + parseInt(e.beta) + " gamma: " + parseInt(e.gamma);
    }, true);

    // デバイスの加速度、重力加速度、回転速度を取得
    window.addEventListener("devicemotion", function(e) {
        var a = e.acceleration;
        var g = e.accelerationIncludingGravity;
        var r = e.rotationRate;
        document.getElementById("ainfo").innerHTML = "X: " + a.x.toFixed(3) + " Y: " + a.y.toFixed(3) + " Z: " + a.z.toFixed(3);
        document.getElementById("ginfo").innerHTML = "X: " + g.x.toFixed(3) + " Y: " + g.y.toFixed(3) + " Z: " + g.z.toFixed(3);
        document.getElementById("rinfo").innerHTML = "alpha: " + r.alpha.toFixed(3) + " beta: " + r.beta.toFixed(3) + " gamma: " + r.gamma.toFixed(3);
    }, true);
};

[html]

<!-- 表示用に準備 -->
<p>デバイスの向き</p>
<p id='oinfo'></p>
<p>加速度</p>
<p id='ainfo'></p>
<p>重力加速度</p>
<p id='ginfo'></p>
<p>回転速度</p>
<p id='rinfo'></p>

こんな感じ↓
f:id:n_1010real:20140421220027j:plain

結果、デバイスの向きは意図通り、傾けた方向によって値が変化。
加速度センサー周りについては、机の上に置きっぱにしても常に変動していてせわしない感じ。
まあ、地球はうごいてるからね。。。という冗談はさておき、実用するなら、閾値で切るなりしないとだめそうという感じですかね。

クロージャとスコープチェーン

クロージャをなるべく簡潔にまとめてみます。

まず、クロージャを正しく理解するためには以下の理解が不可欠なので、その説明をします。

  • javascriptのスコープ
  • スコープチェーン
  • スコープは関数実行時ではなく、関数定義時に決定

javascriptのスコープ

そもそもスコープとは、ある変数や関数が特定の名前で参照される範囲のことです。
で、javascriptのスコープはというと、以下の3種類に分けられます。

  1. グローバルスコープ
  2. 関数スコープ(=ローカルスコープ)
  3. evalスコープ

3.は置いといて、1,2についてサンプルを交えて説明

var foo = 0; // グローバルスコープで定義 
console.log(foo); // 出力:0 
var myFunction1 = function(){ 
    var foo1 = 1; // 関数スコープ(myFunction1)で定義 
    console.log(foo1); // 出力:1 

    // 入れ子な関数 
    var myFunction2 = function() { 
        var foo2 = 2; // 関数スコープ(myFunction2)で定義 
        console.log(foo2); // 出力:2 
    }(); 
    //console.log(foo2); // エラー 
}();
//console.log(foo1); // エラー 

1行目のfooはグローバルスコープに定義された変数で、ソースのどこからでも参照可能です。
foo1,foo2はそれぞれの関数スコープ内で定義されており、その関数内であれば参照が可能ですが、関数外(12,14行目)では参照できません。

スコープチェーン

では、上記のmyFunction1内の入れ子な関数myFunction2内から、foo1は参照できるのでしょうか?

var foo = 0; // グローバルスコープで定義
console.log(foo); // 出力:0
var myFunction1 = function(){
    var foo1 = 1; // 関数スコープ(myFunction1)で定義
    console.log(foo1); // 出力:1
    
    // 入れ子な関数
    var myFunction2 = function() {
        var foo2 = 2; // 関数スコープ(myFunction2)で定義
        console.log(foo2); // 出力:2
        console.log(foo1); // 追加 出力:1
        console.log(foo); // 追加 出力:0
    }();
    //console.log(foo2); // エラー
}();
//console.log(foo1); // エラー

11,12行目でfoo1,fooにアクセスしてみると参照できました。
javascriptでは現在の関数スコープ内に指定された変数がない場合、その親関数の関数スコープ内を探しにいきます。
そして親関数にも変数がない場合には、さらにその親関数を探しにいき、最終的にはグローバルスコープに定義された変数まで確認します。
これをスコープチェーンと呼びます。
グローバルスコープに定義された変数がソースのどこからでも参照可能なのは、スコープチェーンの仕組みがあるからです。

スコープは関数実行時ではなく、関数定義時に決定

上記の関数スコープは実行時に変わることは一切ありません。
例えば、myFunction2が他の関数から参照され、そこで呼び出されたとしても、myFunction2内の変数の解釈はmyFunction2関数スコープ→myFunction1関数スコープ→グローバルスコープというルートを辿って検索されます。
つまり、myFunction2の中からは常にmyFunction1の変数が参照できるということです。
これは、たとえ無名関数であっても同様です。

改めてクロージャとは

改めて、クロージャのサンプルをみてみます。

var myFunction = (function(){
	var foo = 'foo';
	return function(){
		return foo;
	}
})();
console.log(myFunction()); // 出力:foo

3行目で、関数の戻り値として定義されている無名関数は、スコープチェーンにより、親関数内で定義されているfooにアクセスすることができます。
myFunctionにはこの関数が代入され、またスコープは実行時に変わることはないため、変数fooはこのmyFunctionを通じてしかアクセスすることができなくなってしまいました。
つまり、閉じ込められてしまいました。これがクロージャです。

。。。はいこれがクロージャです。。。と言われてもピンとこないですよね。。。
言い換えます。これがクロージャの仕組みです。
クロージャを使ってどんなことができるのかは別の機会に。。。