简体   繁体   English

如何制作 TextGeometry 多线? 我如何将它放在一个正方形内,使其像 html 文本一样在 div 内包装?

[英]How do I make a TextGeometry multiline? How do I put it inside a square so it wraps like html text does inside a div?

I'm making some 3D text using WebGL , three.js , and THREE.TextGeometry .我正在使用WebGLthree.jsTHREE.TextGeometry制作一些 3D 文本。 It's working fine so far.到目前为止它运行良好。 I'm able to create a single line of 3D text.我能够创建一行 3D 文本。

Now I want to create multiline text, like a short paragraph.现在我想创建多行文本,就像一个短段落。 Preferably, I'd like it to wrap naturally when it reaches the border of a box/rectangle its placed it in. I want a similar behavior that standard HTML text has when it's inside of a div, wrapping to multiple lines when it reaches the edge of it's parent div.最好,我希望它在到达放置它的框/矩形的边界时自然换行。我想要标准HTML文本在 div 内部时具有的类似行为,当它到达时换行到多行它的父 div 的边缘。

Here's how I'm creating a single line:这是我创建单行的方式:

 textGeo = new THREE.TextGeometry(
    'Hello there. Am I a paragraph? I hope so.',
    'size': 30
    'height': 2
    'font': 'helvetiker'
    'weight': 'normal'
    'style': 'normal'
    bevelThickness: 0.1
    bevelSize: 0
    bevelEnabled: true
    material: 0
    extrudeMaterial: 1
  )

  materialArray = [
    new THREE.MeshBasicMaterial( { color: 0xFFFFFF  } )
    new THREE.MeshBasicMaterial( { color: 0x666666, shading: THREE.SmoothShading } )
  ]

  textMaterial = new THREE.MeshFaceMaterial(materialArray)
  textGeo = new THREE.Mesh(textGeo, textMaterial)

  textGeo.position.x = -150
  textGeo.rotation.y = de2ra(15)

  scene.add textGeo

How can I make this multiline?我怎样才能制作这个多线? Also, how can I put this inside a square so it wraps?另外,我怎样才能把它放在一个正方形里,让它包裹起来? How do I create the square?如何创建正方形?

One approach might be to draw your text in HTML and render it in the 3D scene .一种方法可能是在 HTML 中绘制文本并在 3D 场景中呈现它

The other approach would be to instantiate the text, test how large it is, and split it up into multiple TextGeometry instances if it is larger than your maximum desired width, offset on the y-axis by the height.另一种方法是实例化文本,测试它有多大,如果它大于所需的最大宽度,则将其拆分为多个 TextGeometry 实例,在 y 轴上偏移高度。 You can get the dimensions of a geometry with geometry.boundingBox (after calling geometry.computeBoundingBox() ) which is a THREE.Box3 .您可以使用geometry.boundingBox (在调用geometry.computeBoundingBox() )获取几何尺寸,它是一个THREE.Box3 Bounding boxes have min and max properties which are vectors representing opposite corner vertices, so you can get the dimensions of a geometry along a given axis by calling eg:边界框具有minmax属性,它们是表示对角顶点的向量,因此您可以通过调用例如:

geometry.boundingBox.max.x - geometry.boundingBox.min.x

The API for three.js is pretty low-level. Three.js 的 API 非常低级。 I do not believe this is possible in general.我不相信这在一般情况下是可能的。 One way you can work around this is to produce multiple TextGeometry instances, one per line, and manually position them at different y coordinates.您可以解决此问题的一种方法是生成多个 TextGeometry 实例,每行一个,并手动将它们定位在不同的 y 坐标处。

Adding this as an updated workaround that can be used to render multiline text using TextGeometry .添加此作为更新的解决方法,可用于使用TextGeometry呈现多行文本。

If you use a template literal string and split the text you want to use for the TextGeometry string onto multiple lines (even including spaces between lines), the TextGeometry will respect these spaces.如果您使用模板文字字符串并将要用于TextGeometry字符串的文本拆分为多行(甚至包括行之间的空格),则TextGeometry将尊重这些空格。 This can be used to manually achive the multiline effect, however this will not "put it inside a square" and cause it to automatically wrap.这可用于手动实现多行效果,但这不会“将其放入正方形”并使其自动换行。

Example例子

let text = `
    first line.
    second line.

    third line.
`;

objectGeometry = new THREE.TextGeometry(text, {
    font: font,
    size: 10,
    height: 0,
    curveSegments: 10
}).center();

Following up on the previous post.跟进之前的帖子。 You can also break lines with \\n and text geometry will respect it.您还可以使用\\n换行,文本几何图形会尊重它。 This however, doesn't solve the "html-like wrapping"然而,这并不能解决“类似 html 的包装”

ie IE

let text = `first line. \n second line. \n third line.`;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM