トップへ(mam-mam.net/)

テキストの表示 ~Webサイトで3Dコンテンツ(Three.js)デザイン

検索:

Three.jsでテキストを表示する(Three.js[r145]を使用)

three.jsでテキストを表示する方法といえばFontLoaderとTextGeometryを使って3Dテキストを表示するのが常套手段ですが、 json形式の大きなサイズのフォントファイルが必要になりロードにも時間がかかったりします。
そこで本サイトでのサンプルは、表示したいテキストから画像を作成し、 その画像をテクスチャとして平面に貼り付けて3D空間に2D文字を表示させます。

実例

マウス左ドラッグで回転、右ドラッグでカメラの移動、ホイールで拡大縮小できます。
スワイプで回転、画面に2本指を触れてなぞるとカメラの移動、ピンチイン/アウトで拡大縮小できます。

ソースコード

    ・・・
    //■文字を表示する処理
    //文字を画像に変換
    png=CreateTextPng("文字を表示","96px","#ffffff");
    //文字の画像のテクスチャをロード
    textureText = new THREE.TextureLoader().load( png.img );
    //マテリアル(材質)の作成
    materialText=new THREE.MeshBasicMaterial({
      color:0xffffff, map:textureText ,side:THREE.FrontSide,
      transparent:true, opacity:1.0,
    });
    //平面ジオメトリの作成
    planeGeo=new THREE.PlaneGeometry(png.w/10, png.h/10,1,1);
    //メッシュの作成
    meshText=new THREE.Mesh(planeGeo,materialText);
    meshText.position.set(0, 0, 10.1);
    scene.add(meshText);
    ・・・

  //(文字列, 文字サイズ, 文字色)を指定すると{img:png画像, w:幅, h:高さ}を返す
  function CreateTextPng(text,size,color){
    let can=document.createElement("canvas");
    let ctx=can.getContext("2d", {willReadFrequently:true});
    family=
      'Verdana,Roboto,"Droid Sans","游ゴシック",YuGothic,"メイリオ",Meiryo,'+
      '"ヒラギノ角ゴ ProN W3","Hiragino Kaku Gothic ProN","MS Pゴシック",sans-serif';
    ctx.font=size+" "+family;
    ctx.baseLine="top";
    ctx.textAlign="left";
    let measure=ctx.measureText(text);
    can.width=measure.width;
    can.height=measure.fontBoundingBoxAscent+measure.fontBoundingBoxDescent;
    //幅高さを変更すると再設定が必要になる
    ctx.font=size+" "+family;
    ctx.baseLine="top";
    ctx.textAlign="left";
    //透明にする
    ctx.globalCompositeOperation = 'destination-out';
    ctx.fillStyle="rgb(255,255,255)";
    ctx.fillRect(0,0,can.width,can.height);
    //通常描画にする
    ctx.globalCompositeOperation = 'source-over';
    ctx.fillStyle=color;
    ctx.fillText(text,Math.abs(measure.actualBoundingBoxLeft),measure.actualBoundingBoxAscent);
    let png=can.toDataURL('image/png');
    return {img:png, w:can.width, h:can.height};
  }