Ionicで電卓を作成したので振り返る(Directive編)

Ionicで電卓を作成したので振り返る(Component編)の続きです。
今回は、Directiveを使った文字サイズの自動調整部分になります。
主に以下の内容について書きます。

・変更検知
・文字サイズの変更(謎の計算式)

作ったDirectiveの説明

フォントサイズを自動調整するDirectiveを作りました。名前はflowtypeといいます。ソースコードは以下。

Ionicで作成された電卓です。. Contribute to xcalculator development by creating an account on GitHub.

極めて地味な変化ですが、入力された文字数に応じてフォントサイズを自動調整しています。ちょうど下の画像のような感じです。

Screen Shot 2017-09-13 at 23.39.54.png

Screen Shot 2017-09-13 at 23.40.01.png
※わずかながら上の画像よりフォントサイズが小さい

使い方

flowtypeディレクティブはInputとして以下の2つをもちます。

・flowtype
 入力される文字列です。

・size
 フォントのデフォルトサイズです。

大体HTMLで記述するとこんな感じです。

<div flowtype="あいうえお" size=7></div>

変更検知

Angular標準のOnChangesを使用しています。
コードで書くと以下のような感じ。

import { OnChanges, Directive, ElementRef, Input } from '@angular/core';

@Directive({
    selector: '[flowtype]' // Attribute selector
})
export class FlowtypeDirective implements OnChanges {
   @Input('flowtype') flowtype: any;
   @Input() size: number;

   /** 略 **/
   ngOnChanges(changes:any) {
        /** 略 **/
   }
}

FlowtypeDirectiveはインポートしたOnChangesモジュールを継承しています。OnChangesモジュールを継承することでngOnChanges()メソッドを呼び出せるようになります。
今回だと、文字数としてインプットされているflowtype変数が変更されるたびにngOnChanges()メソッドが呼び出されるので、このなかでフォントサイズ変更の処理を記述しています。

文字サイズの変更(謎の計算式)

以下が文字サイズの変更処理になります。本ディレクティブの主目的ですね。

changeFontSize(){
    var fontSize = this.size;
    var len = this.flowtype.length - 1;
    var newSize = (100 / len) * 1.7;
    if(this.size > newSize){
        fontSize = newSize;
    }
    this.el.nativeElement.style.fontSize = fontSize + "vw";
    this.el.nativeElement.innerHTML = this.flowtype;
}

話としてはめちゃくちゃ単純で以下の計算式でフォントサイズ(vw)を求めて、それが、デフォルトサイズより小さい値であれば、フォントサイズとして設定するといった処理になっています。

・フォントサイズ(vw) = 100 / 文字の長さ

vwはビューポートの何分の1か?という指定ができる単位です。

この計算式では謎の数値の1.7をかけています。こいつが何かと言いますと、何者か自分でもわかっておらず、とりあえずないと文字が小さすぎてこれ以上大きい数値だと文字がはみ出ると行った始末です。
おそらく、3文字ごとに挟んでいるカンマの影響でしょうか?
フォントが等幅フォントでないため、カンマの用に横幅が小さい文字が複数含まれると幅が足りなくなってしまうのでしょう。と思います。

まとめ

今回は、文字列可変変更のDirective作成を振り返りました。
よくありそうな機能。かつswiftとかだとフレームワークがサポートしてくれてそうな機能ですが、いざ、処理を考え実装するとなると色々考えないといけないことがあって面倒ですね。

この記事書く時に改めて調べたら既に同じDirectiveは世の中にたくさん存在してました。しかも、私のとりあえず動くものに比べると間違いなく出来がよいでしょう。
いつかこの文字サイズ変更Directiveも他のDirectiveを参考に書き直そうと思います。

ng2-fittext - An Angular2 directive for autoscale the font size of an element to fit an up
[紹介元] CSSタグが付けられた新着投稿 – Qiita Ionicで電卓を作成したので振り返る(Directive編)

関連記事