Fallout4面白いですね。日本語の行間とか最悪ですね。読みづらすぎますね。
前回はとりあえず実現可能性を探っていましたが、今回は本格的に機能を検討したいとお思います。
カーニングデータを分離
エンジン部分とデータを分離しておいた方が、Fontごとにデータを作ることができて便利ですよね。JSONも良いですが、今回は別のJSファイルに記述します。
実際に使う場合はconcatしても良いと思います。今回はヒラギノフォント用で進めます。
JSファイル名を「PIPKerningHiragino.js」としてます。
JSのクラス名は「PIPKergninTable」、これはすべてのフォントで同じです。ファイル名で識別します。
(function(global){
"use strict";
// モジュール設定
global["pipboy"] = global.pipboy || {};
var module = global.pipboy;
module.PIPKerningTable = function(){
};
})((this || 0).self || global);
行頭データを追加する
まずは行頭ぞろえ用のデータを検討します。
"「"
"("
は文字の半分だけ内側に入ってしまいます。これ毎回きになりますよね。CSSではネガティブマージンで調整することができます。
クラス変数にマージンの値をもたせます。
// Beginning of Line (行頭)
module.PIPKerningTable.BOL = {
'(': '-0.5',
'「': '-0.5'
}
これで行頭ぞろえの準備はできたので、一旦エンジン側に移ります。行頭以外のカーニングは、エンジンの基本的な実装ができてから再度設定します。
カーニングエンジンの設計
カーニングを適用する方法はシンプルにCSSのクラス設定のみにします。
カーニング指定するDOMに「pip-kerning」クラスを指定してください。あとは自動的に設定されると便利ですね。
<h1 class="pip-kerning">「見出し1」です。classにpip-kerningを設定</h1>
自動的に実装するので、
- DOM要素を抽出
- spanタグで一文字づつ囲みカーニング設定
- 行頭設定
の順番で検討してみます。
PIPKerningクラスを作る
カーニングエンジンJSを作ります。「PIPKerning.js」とします。クラス名も「PIPKerning」です。
module.PIPKerning = function(){
// プロパティなど
};
まずは「pip-kerning」でDOM要素を抽出します。
var $elements = document.getElementsByClassName('pip-kerning');
これでHTML上のすべての要素を取得しました。$elementsは配列です。
各要素をそれぞれ処理します。
var $elements = document.getElementsByClassName('pip-kerning');
var len = $elements.length;
for(var i = 0; i < len; ++i){
var str = $elements[i].innerHTML;
var newHTML = this.__define(str); // __defineはプライベートメソッド
$elements[i].innerHTML = newHTML;
}
innerHTMLでテキストを抜き出し、this.__defineでspanタグ実装します。最後に新しいhtmlを追加します。
次に__defineの実装をします。
処理部分を抜き出すのこんな感じです。文字をバラバラにしてspanで囲むだけです。カーニング設定はまだです。
ただし、インラインスタイルで「inline-block」を必ず指定してください。これは行頭ぞろえで使います。
var characters = str.split('');
var table = module.PIPKerningTable.table;
var len = characters.length;
var output = "";
for(var i = 0; i < len; ++i){
output += '<span style="display: inline-block;">' + characters[i] + '</span>';
}
return output;
行頭ぞろえ
次に行頭ぞろえの処理を実装します。行頭はウィンドウサイズで変わる可能性があります。(デバイスサイズ依存)
これは面倒くさいですね。
今回はカーニング領域のサイズを取得し、各文字のサイズと領域のサイズを比較し行頭を見つけます。
// 行頭処理
var $childs = $elements[i].getElementsByTagName("span"); // 各文字(1文字)
var rowWidth = $elements[i].clientWidth;
var currentRowWidth = 0; // 行
for(var j = 0; j < $childs.length; ++j){
currentRowWidth += $childs[j].clientWidth; // 行の横幅を加算していく。文字数が増えれば大きくなる
if(currentRowWidth >= rowWidth || j == 0) { // 行の幅と、最初の一文字目を行頭と判定
var bol = PIPKerningTable.BOL[$childs[j].innerHTML] + 'em';
if(bol) {
$childs[j].style.marginLeft = bol;
trace($childs[j].style.marginLeft)
}
currentRowWidth = 0;
}
}
行の横幅はclientWidthで取得し、forループの中で各文字のサイズを調べます。inline-block設定がないと、spanの横幅を取得できません。ご注意ください。
これで行頭ぞろえが実現できました!
ブラウザのリサイズは上の処理を再度実行すればできますね。その辺は次回に...
今回はここまでです。つぎは本題の文字ごとのカーニング実装です。