jnobuyukiのブログ

研究していて困ったことやその解決に関するメモ。同じように困ったあなたのために。twitter ID: @j_nobuyuki

文字ごとのフォントを変えてみる

特定の要素やある段落のフォントを設定するのはCSSで簡単に設定できます。しかし、今回は一続きの文の各文字のフォントを変えてみます。こういう時はJavaScriptが便利です。

f:id:jnobuyuki:20150124054515j:plain

テキストボックスの設定(HTML)

今回は、入力された文を読み取って、各文字のいろいろな属性をランダムに変更させて表示してみます。まずは、文字の入力用にテキストボックスを用意します。長い文でも入力できるように、複数行の入力が可能なtextareaタグを使います。

textareaタグの属性で、maxlengthは最大の文字数、colsとrowsはそれぞれ一行当たりの文字数と行数を決めています。placeholderは何を書くべきかのヒントをテキストボックス内に表示するのに利用できます。

<form>
<textarea placeholder = "ここに好きな言葉を書いてください" id = "inputtxt" maxlength = "72" cols = "40" rows = "4" ></textarea>
<input type = "button" id = "startbutton"> 

</form>

JavaScript

ボタンクリック時の関数呼び出し

addEventListenerを設定するとクリックしたときの関数呼び出しを行えます。

document.getElementById("startbutton").addEventListener("click",charparse);
フォントキーワードの配列

ランダムにフォントを設定するために、フォントのキーワードを含む配列を作成します。今回はsans-serif(ゴシック体),serif(明朝体),cursive(手書き文字),monospace(等幅)を設定します。このほかにfantasyというキーワードもあります。ただし、和文ではゴシック体になることが多いため、今回は用いません。

var fontarr = ['sans-serif','serif','cursive','monospace'];
入力された文字を一文字ずつの配列に分解

splitを使うと簡単に文字列を各文字を要素とする配列にできます。HTMLで設定したtextareaの入力はvalueプロパティで取得できます。splitは文字列を配列に変換する関数で、区切り文字を引数としますが、各文字に切り離す場合は""とします。

var chararr = document.getElementById("inputtxt").value.split("");
色々な属性をランダムに設定

今回は、フォント、文字の大きさ、文字の角度をばらつかせてみましょう。上で作った配列を利用して、各文字に属性をランダムに設定し、オブジェクトの配列として保存します。ポイントはMath.random()を使って乱数を発生させることです。
文字の大きさはウインドウの横幅(innderWidth)の2.5%から5%幅でばらつかせてみましょう。
角度は‐10°から10°の範囲にします。

//フォント
var fontPointer = Math.floor(Math.random() *100) % 4;
var currentFont = fontarr[fontPointer];

//文字の大きさ
var currentSize = Math.floor(Math.random() * window.innerWidth * 0.025) + Math.floor(window.innerWidth * 0.025);

//文字の角度
var currentAngle = Math.floor(Math.random() * 20) - 10;

このほかに文字の位置(x,y)を配列に含ませておくと便利です。今回のような場合、SVGのテキストでは、各文字について細かく位置を設定する必要があるからです。
例として、1行に18文字でそれ以上は改行する場合を示します。

//一文字あたりのスペースを定義
var len = window.innerWidth * 0.05;

//最後に保存する配列をあらかじめ定義
var arr = new Array();

//chararrの長さだけ繰り返し
for (var i = 0;i < chararr.length; i += 1){
 var currentx;
  var currenty;
  var cumy = len;
  //最初の1文字、19文字目、37文字目などでx,yを調整 
  if(i % 18 == 0) {
    currentx = len;
    cumx += len;
    cumy += len;//1文字分下がる
    curenty = cumy;
  } else {
    currentx = cumx;
    cumx += len;
    currenty = cumy;
  }
arr.push(new Object({item: chararr[i], size: currentSize, angle: currentAngle, startx: currentx, starty: currenty, font: currentFont})
}

||

*** D3.jsを利用して文字列を表示
D3のチェインを使うと簡単に設定できます。

>|javascript|

var svg = d3.select("div").append("svg").attr("width", 1024).attr("height",768);

svg.append("g").selectAll("text").data(arr).enter().append("text")
.attr("width",function(){return window.innerWidth* 0.05;})
.attr("height",function(){return window.innerWidth* 0.05;})
.attr("x",function(d){return d.startx;})
.attr("y",function(d){return d.starty;})
.text(function(d){return d.item;})
.style("font-family",function(d){return d.font;})
.style("fill","#FFFFFF")//黒い背景に白い文字
.style("font-size",function(d){return d.size;})
.attr("transform",function(d){return "rotate(" + +d.angle + "," d.startx + window.innerWidth * 0.025 + ",", + +d.starty + window.innerWidth *0.025 + ")"});//文字の中心で回転

補足ウエブフォントの利用

今回はフォントのキーワードを利用しましたが、ウエブフォントを利用するともっと個性的な表示が可能です。

追記(2015年1月24日)

gistsにサンプルを置いてみましたので、よろしかった試してみてください。
文字ごとに属性の値を変えるChanging font properties by each character