40

three.jsで作成した3Dモデルがあります。いくつかのデータに基づいて、小さなテキスト ラベルで装飾された一連の矢印を作成したいと考えています。これらのラベルは 2D である必要があります。

別のキャンバス要素を使用してテクスチャを作成し、それを 3D モデルで使用するか、3D モデルのキャンバス要素の上に HTML を使用します。

これをどうしようか迷っています。これを行う「正しい」方法はどれですか? 提案やサンプルコードは大歓迎です!

4

8 に答える 8

47

テキストが常に一番上に表示され(たとえば、オブジェクトが他の何かによってブロックされている場合でも、そのテキストラベルは引き続き表示され、他のすべての上に表示されます)、テキストが影響を受けないことを気にしない場合ライト/シャドウなどのレンダリングの場合、HTMLが最も簡単な方法です。

サンプルコードは次のとおりです。

var text2 = document.createElement('div');
text2.style.position = 'absolute';
//text2.style.zIndex = 1;    // if you still don't see the label, try uncommenting this
text2.style.width = 100;
text2.style.height = 100;
text2.style.backgroundColor = "blue";
text2.innerHTML = "hi there!";
text2.style.top = 200 + 'px';
text2.style.left = 200 + 'px';
document.body.appendChild(text2);

テキストを配置するy座標とx座標を(それぞれ)style.top変数とstyle.left変数に200で置き換えます。これらは正の値になります。ここで、(0,0)はキャンバスの左上です。キャンバスの3Dポイントからブラウザウィンドウのピクセルの2Dポイントに投影する方法のガイダンスについては、次のようなコードスニペットを使用してください。

function toXYCoords (pos) {
        var vector = projector.projectVector(pos.clone(), camera);
        vector.x = (vector.x + 1)/2 * window.innerWidth;
        vector.y = -(vector.y - 1)/2 * window.innerHeight;
        return vector;
}

事前にcamera.updateMatrixWorld()を呼び出していることを確認してください。

于 2013-03-06T20:54:13.777 に答える
20

3Dシーンの一部としてキャンバスオブジェクトからのテキスト(または任意の画像)を実際に含めたい場合は、 http://stemkoski.github.com/Three.js/Texture-From-Canvasでサンプルコードを確認してください。 html

于 2013-03-12T21:54:22.253 に答える
10

更新: このメソッドは現在非推奨であり、CPU が重いため、使用しないでください。

three.jsベースの別のソリューションを見つけました。

var textShapes = THREE.FontUtils.generateShapes( text, options );
var text = new THREE.ShapeGeometry( textShapes );
var textMesh = new THREE.Mesh( text, new THREE.MeshBasicMaterial( { color: 0xff0000 } ) ) ;
scene.add(textMesh);
// Example text options : {'font' : 'helvetiker','weight' : 'normal', 'style' : 'normal','size' : 100,'curveSegments' : 300};

このテキストを動的に編集するには、

var textShapes = THREE.FontUtils.generateShapes( text, options );
var text = new THREE.ShapeGeometry( textShapes );
textMesh.geometry = text;
textMesh.geometry.needsUpdate = true;
于 2015-06-11T08:17:47.087 に答える
8

あなたのためにそれを行うモジュールをNPMで公開しました:https://github.com/gamestdio/three-text2d

キャンバスを手動で処理しなくても、レンダリングされたテキストをSprite使用できます。Mesh

例:

var Text2D = require('three-text2d').Text2D

var text = new Text2D("Hello world!", { font: '30px Arial', fillStyle: '#000000', antialias: true })
scene.add(text) 
于 2016-01-23T16:27:04.723 に答える
6

2D キャンバスを作成し、css を使用して webgl キャンバスの上部に配置できます。次に、2D キャンバス コンテキストによって提供されるctx.fillText(text,x,y)またはメソッドを使用して、その上にテキストを描画できます。ctx.strokeText(text,x,y)このメソッドを使用すると、矢印やメーターなど、テキスト以外のものを描画できます。

@kronuus が提案する方法を使用して、ポイントを 3D 空間から 2D 空間に変換できます。

于 2013-03-08T15:16:41.910 に答える
2

@LeeStemkoski による応答は非常に役に立ちました。ただし、テキストが矢印に追従するように、つまり矢印が移動したり、回転したりした場合に備えて、コードにわずかな変更を加える必要があります。

次のコードを参照してください

                        var canvas1 = document.createElement('canvas');
                        var context1 = canvas1.getContext('2d');
                        context1.font = "Bold 10px Arial";
                        context1.fillStyle = "rgba(255,0,0,1)";
                        context1.fillText('Hello, world!', 0, 60);

                        // canvas contents will be used for a texture
                        var texture1 = new THREE.Texture(canvas1)
                        texture1.needsUpdate = true;

                        var material1 = new THREE.MeshBasicMaterial({ map: texture1, side: THREE.DoubleSide });
                        material1.transparent = true;

                        var mesh1 = new THREE.Mesh(
                            new THREE.PlaneGeometry(50, 10),
                            material1
                          );
                        mesh1.position.set(25, 5, -5);
                        mesh1.rotation.x = -0.9;
                        shape.add(mesh1);
                        // Note that mesh1 gets added to the shape and not to the scene

                       scene.add(shape)

ご覧のとおり、テキスト ( mesh1)shapeシーンに追加するのではなく、 (「矢印」)に追加するのがコツです。

これが役立つことを願っています。

于 2016-03-30T10:52:59.823 に答える