接下来:three.js 2D Text sprite labels
我发现了如何在three.js二维文本精灵,我需要它的React三纤维现在。
我的索引上有这个。js:
<Canvas
gl={{}}
orthographic camera={{zoom: 20, position: [28, 22, 26]}}
color={'#FF3333'}
>
<ambientLight />
<pointLight position={[0, 10, 30]} />
<Box className="boxMesh" color={'#FF3333'} active={active} setActive={setActive} position={[-1, 0, 10]} />
<Text position={[-4, -4, 10]} />
<Controls />
</Canvas>
盒子工作正常,文本我不知道如何转换的代码在react三纤维,Text.js
function Text(props) {
// This reference will give us direct access to the mesh
const mesh = useRef()
function makeTextSprite( message, parameters )
{
if ( parameters === undefined ) parameters = {};
var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial";
var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18;
var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4;
var borderColor = parameters.hasOwnProperty("borderColor") ?parameters["borderColor"] : { r:0, g:0, b:0, a:1.0 };
var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?parameters["backgroundColor"] : { r:255, g:255, b:255, a:1.0 };
var textColor = parameters.hasOwnProperty("textColor") ?parameters["textColor"] : { r:0, g:0, b:0, a:1.0 };
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.font = "Bold " + fontsize + "px " + fontface;
var metrics = context.measureText( message );
var textWidth = metrics.width;
context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + "," + backgroundColor.b + "," + backgroundColor.a + ")";
context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + "," + borderColor.b + "," + borderColor.a + ")";
context.lineWidth = borderThickness;
roundRect(context, borderThickness/2, borderThickness/2, (textWidth + borderThickness) * 1.1, fontsize * 1.4 + borderThickness, 8);
context.fillStyle = "rgba("+textColor.r+", "+textColor.g+", "+textColor.b+", 1.0)";
context.fillText( message, borderThickness, fontsize + borderThickness);
var texture = new THREE.Texture(canvas)
texture.needsUpdate = true;
var spriteMaterial = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false } );
var sprite = new THREE.Sprite( spriteMaterial );
}
function roundRect(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x + r, y); ctx.lineTo(x + w - r, y); ctx.quadraticCurveTo(x + w, y, x + w, y + r); ctx.lineTo(x + w, y + h - r); ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h); ctx.lineTo(x + r, y + h); ctx.quadraticCurveTo(x, y + h, x, y + h - r); ctx.lineTo(x, y + r); ctx.quadraticCurveTo(x, y, x + r, y); ctx.closePath(); ctx.fill(); ctx.stroke(); }
return (
<>
<mesh
sprite={makeTextSprite('text')}
{...props}
ref={mesh}
className="text"
>
</mesh>
</>
)
}
export default Text
如果我可以在我的画布上使用scene.add,我只需要使用makeTextSprite函数就可以轻松地添加它,但是我需要作为文本组件添加,我该怎么做呢?
2条答案
按热度按时间i5desfxk1#
找到了一个临时的解决方案,不是那么糟糕,但文本有点颗粒感...(下面的版本2看起来更好,但使用另一个库)
文本看起来更好,保持比例上的低值,并通过更改fontSize更改尺寸
一个二个一个一个
ttcibm8c2#
你可以使用react-three/drei库来获得更好的文本质量,它使用msdf创建文本。