あさた研メモ

主に私が気づいたこととか困った時のメモとか書き留めとく用。

three.jsのTextGeometryをTypescriptでやる(r82)

この記事はPMOB Advent Calendarの15日目の記事です。 www.adventar.org

前の記事: ムフフ簡易VRやってみた - ざっきーの雑記ー
次の記事: まだ

TL;DR

three.jsのr74〜 + TypescriptでTextGeometryつくるのはキレる。

というわけで

typescript + threejsの話です。
threejsを使ってtypescriptでコーディングしてコンパイルすることはできます。
前回記事でもちょっと話しましたが。

諸事情でテキストを表示したくて、TextGeometryというのがあるので使いました。
が、日本語も扱いたかったのでフォントファイルを読み込ませないといけません。

フォントファイルはjsonファイルにしないといけないので、 typeface.jsでttfを変換します。

最初書いたコードがコレです。 ちなみにclass内に書いています。
(以後、フォントファイルのある場所をfont_pathと表現します)

class threeDrawing{
...
  function Text(){
    let t = this;
    let loader = new THREE.FontLoader( text: string );
    loader.load('font_path', function( font ){
      let geometry = new THREE.TextGeometry(text, {
        font: font,
        size: 5,
        ...
        }
      );
      let material = ...
      let mesh = ...
      t.scene.add( mesh );
    });
  }
...
}

エラーが出ます。
許されないです。

何がいけないかと言うと、

  1. TextGeometryで与えるパラメータは{}じゃなくてTextGeometryParametersだよ
  2. fontはtype Fontじゃないとだめだよ

とのこと。


TextGeometryParameters

1.に関しては、

let parameters: THREE.TextGeometryParameters = {
  font: font,
  size: ...
  ...
};

といった感じで型を指定してやればいいです。
ちなみに、TextGeometryParametersはInterfaceです


THREE.Fontまわり

さて、2.に関してですが…

いや、FontLoaderで読み込んでるんだからtype Fontだろ!と思いますよね…
違うんですよね。あれtype Objなんですよ。

じゃあtype Fontってどう作るの?というと、
THREE.Fontです。

さて、THREE.Fontの使い方ですが…
THREE.Font( font_path )ではないです。

私の実装はこうなりました。

public FontobjLoad(): void{
  // thisの保持をする
  // fontはインスタンス変数this.fontに格納
  let t = this;
  $.ajax({
    type: "get",
    url: 'font_path',
    async: false,
    dataType: 'json',
    success: function( data ){
        t.font = new THREE.Font( data );
    }
  });
}

は?

って感じですが、これでうまくいきます。

これでフォントデータを読み込めます。

THREE.Fontの引数はjson stringです。
Objectではないです
フォントのjsonファイルを読み込んで、そのjsonをTHREE.Fontに渡してやります。

あとは、このfontを使ってTextGeometryを作るだけです。
fontをさっきの1.でのparametersにぶち込んで、こんな感じ。

let parameters: THREE.TextGeometryParameters = {
  font: this.font,
  size: ...
  ...
};
let geometry = new THREE.TextGeometry( text, parameters );
let material = ...
let mesh = ...
this.scene.add( mesh );

FontLoader、不良では???という感じですね。


さいご

Typescriptはコンパイラが注意を出してくれるので本当にこういうエラーに対処しやすくなりました。
とてもありがたい。

ただ、DefinitelyTypedのTHREEの定義ファイルに関して、 おそらくr81〜は対応してません。(2016.12.14現在)
というのも、r81で追加されたEdgesGeometryに対応してないからです。
r81以降はEdgesHelperは非推奨(というか使えない)ですからね。

うどん食いたい