SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

JavaScriptとWebGLによるはじめての3Dプログラミング

「three.js」でつくるお手軽3Dマンガ作成ソフト - 後編

JavaScriptとWebGLによるはじめての3Dプログラミング(3)

ダウンロード sample.zip (335.2 KB)

フキダシの表示

フキダシの表示

 第1回の「Canvasをテクスチャとして読み込み」の応用です。「Canvas」をテクスチャにできるということは、「Canvas」の描画機能で生成した画像を自由にテクスチャに適用できるということです。この方法を使えば、文字列やその背景をテクスチャにできます。この仕組みを使い、フキダシを作成します。

 ここから先は、「Canvas」の描画処理の話になります。フキダシを作る際のコツは、「Canvas」の「2d Context」の「textBaseline」属性に、「"middle"」を設定することです。

 「Canvas」の文字列描画の仕様は、英語を描画することを想定して作られています。そのため、文字のベースラインのデフォルトは 「"alphabetic"」となっており、アルファベットを書く時の補助線の位置が基準になっています。この線に合わせて配置すると、日本語では問題が生じます。

 この文字のベースラインを、日本語の文字の中央位置に指定すれば、上下のフキダシの枠との距離が、上端と下端で等しくなります。

 以下、角丸四角でフキダシを作るサンプルとして「crocro.bc.viewFukidasi.js」を掲載します。

「crocro.bc.viewFukidasi.js」
//= サンプル:フキダシの表示

//== フキダシの表示
crocro.bc.viewFukidasi = function() {
    // 変数の初期化
    var d3 = crocro.bc.d3;    // 3D格納用
    var plt;

    // 要素の作成と格納
    plt = crocro.bc.mkFukidasi(true);    // ポリゴン範囲付き
    plt.position.x = -100;
    d3.scene.add(plt);

    plt = crocro.bc.mkFukidasi(false);    // ポリゴン範囲なし
    plt.position.x = 100;
    plt.position.y = -100;
    plt.position.z = 2;
    d3.scene.add(plt);

    crocro.bc.render();
};

//== 画像ポリゴンの作成
crocro.bc.mkFukidasi = function(isDrwBck) {
    // キャンバスの作成
    var w = 1024;
    var h = 1024;
    var cnvs = $('<canvas width=' + w + ' height=' + h + '>').get(0);
    var cntxt = cnvs.getContext("2d");

    // フキダシ描画
    crocro.bc.drwFukidasi(cntxt, w, h, isDrwBck);

    // テクスチャの作成
    var texture  = new THREE.Texture(cnvs);
    texture.needsUpdate = true;    // 画像読み込み後の更新を指定

    // マテリアルとメッシュの作成
    var material = new THREE.MeshBasicMaterial({map: texture});

    // 透明部分の処理
    if (! isDrwBck) {
        material.transparent = true;    // 透明を有効
        material.alphaTest = 0.5;        // これを追加するときちんと表示される
    }

    var mesh = new THREE.Mesh(
        new THREE.PlaneGeometry(500, 500, 4, 4),
        material
    );

    // メッシュを戻して終了
    return mesh;
};

//== フキダシ描画
crocro.bc.drwFukidasi = function(cntxt, cnvsW, cnvsH, isDrwBck) {
    // テクスチャ サイズが分かるように背景を描画
    if (isDrwBck) {
        cntxt.fillStyle = "#ff0000";
        cntxt.globalAlpha = 0.5;
        cntxt.fillRect(0, 0, cnvsW, cnvsH);
        cntxt.globalAlpha = 1;
    }

    // 表示する文字列
    var strArr = "abcdefg\nあいうえおかきくけこ\n聖徳太子".split("\n");

    // 文字列描画の初期化
    var fntSz = 64;
    cntxt.font = fntSz + 'px ""';
    var mrgnX = fntSz;
    var mrgnY = fntSz * 0.5;
    var lnH   = fntSz * 1.4;

    // 文字列の最大幅を求める
    var maxW = 0;
    for (var i = 0; i < strArr.length; i ++) {
        var w = cntxt.measureText(strArr[i]).width;
        if (w > maxW) maxW = w;
    }

    // フキダシのサイズを求める
    var fkdsW = maxW + mrgnX * 2;
    var fkdsH = strArr.length * lnH + mrgnY * 2;
    var fkdsX = (cnvsW - fkdsW) / 2;
    var fkdsY = (cnvsH - fkdsH) / 2;
    var fkdsR = fntSz;

    // 角丸矩形の描画
    crocro.bc.pathRoundRect(cntxt, fkdsX, fkdsY, fkdsW, fkdsH, fkdsR);

    cntxt.fillStyle = "#ffffff";
    cntxt.fill();    // 塗り潰し

    cntxt.lineWidth = 10;
    cntxt.strokeStyle = "#000000";
    cntxt.stroke();    // 縁の描画

    // 文字列設定の初期化
    cntxt.textBaseline = "middle";    // 中央
    cntxt.fillStyle = "#000000";
    var x = fkdsX + mrgnX;
    var y = fkdsY + mrgnY + lnH / 2;

    // 文字列の描画
    for (var i = 0; i < strArr.length; i ++) {
        cntxt.fillText(strArr[i], x, y);
        y += lnH;
    }
}

//== 角丸矩形
crocro.bc.pathRoundRect = function(cntxt, x, y, w, h, r) {
    var pi = Math.PI;
    cntxt.beginPath();
    cntxt.arc(x + r,     y + r,     r, -pi,     -pi / 2, false);
    cntxt.arc(x + w - r, y + r,     r, -pi / 2, 0,       false);
    cntxt.arc(x + w - r, y + h - r, r, 0,       pi / 2,  false);
    cntxt.arc(x + r,     y + h - r, r, pi / 2,  pi,      false);
    cntxt.closePath();
}

次のページ
箱人形の表示

この記事は参考になりましたか?

JavaScriptとWebGLによるはじめての3Dプログラミング連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7210 2013/06/25 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー