Skip to content

Commit

Permalink
feat(troika-three-text): add curveRadius for applying cylindrical cur…
Browse files Browse the repository at this point in the history
…vature
  • Loading branch information
lojjic committed Feb 13, 2021
1 parent cfe5d27 commit 6fdfbbf
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/troika-3d-text/src/facade/Text3DFacade.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const TEXT_MESH_PROPS = [
'strokeColor',
'strokeWidth',
'strokeOpacity',
'curveRadius',
'depthOffset',
'clipRect',
'orientation',
Expand Down
8 changes: 8 additions & 0 deletions packages/troika-three-text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ Use the `material` property if you want to control aspects of the material other

Default: _none_ - uses the color of the `material`

### `curveRadius`

Defines a cylindrical radius along which the text's plane will be curved. Positive numbers put the cylinder's centerline (oriented vertically) that distance in front of the text, for a concave curvature, while negative numbers put it behind the text for a convex curvature. The centerline will be aligned with the text's local origin; you can use `anchorX` to offset it.

Since each glyph is by default rendered with a simple quad, each glyph remains a flat plane internally. You can use [`glyphGeometryDetail`](#glyphgeometrydetail) to add more vertices for curvature inside glyphs.

Default: `0`

### `depthOffset`

This is a shortcut for setting the material's [`polygonOffset` and related properties](https://threejs.org/docs/#api/en/materials/Material.polygonOffset), which can be useful in preventing z-fighting when this text is laid on top of another plane in the scene. Positive numbers are further from the camera, negatives closer.
Expand Down
13 changes: 13 additions & 0 deletions packages/troika-three-text/src/Text.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ const Text = /*#__PURE__*/(() => {
*/
this.anchorY = 0

/**
* @member {number} curveRadius
* Defines a cylindrical radius along which the text's plane will be curved. Positive numbers put
* the cylinder's centerline (oriented vertically) that distance in front of the text, for a concave
* curvature, while negative numbers put it behind the text for a convex curvature. The centerline
* will be aligned with the text's local origin; you can use `anchorX` to offset it.
*
* Since each glyph is by default rendered with a simple quad, each glyph remains a flat plane
* internally. You can use `glyphGeometryDetail` to add more vertices for curvature inside glyphs.
*/
this.curveRadius = 0

/**
* @member {string} font
* URL of a custom font to be used. Font files can be any of the formats supported by
Expand Down Expand Up @@ -562,6 +574,7 @@ const Text = /*#__PURE__*/(() => {
uniforms.uTroikaStrokeWidth.value = strokeWidth
uniforms.uTroikaStrokeOpacity.value = strokeOpacity
uniforms.uTroikaFillOpacity.value = fillOpacity == null ? 1 : fillOpacity
uniforms.uTroikaCurveRadius.value = this.curveRadius || 0

let clipRect = this.clipRect
if (clipRect && Array.isArray(clipRect) && clipRect.length === 4) {
Expand Down
9 changes: 9 additions & 0 deletions packages/troika-three-text/src/TextDerivedMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ uniform bool uTroikaUseGlyphColors;
uniform float uTroikaDistanceOffset;
uniform float uTroikaBlurRadius;
uniform vec2 uTroikaPositionOffset;
uniform float uTroikaCurveRadius;
attribute vec4 aTroikaGlyphBounds;
attribute float aTroikaGlyphIndex;
attribute vec3 aTroikaGlyphColor;
Expand Down Expand Up @@ -43,6 +44,13 @@ position.xy = mix(bounds.xy, bounds.zw, clippedXY);
uv = (position.xy - uTroikaTotalBounds.xy) / (uTroikaTotalBounds.zw - uTroikaTotalBounds.xy);
float rad = uTroikaCurveRadius;
if (rad != 0.0) {
float angle = position.x / rad;
position.xz = vec2(sin(angle) * rad, rad - cos(angle) * rad);
normal.xz = vec2(sin(angle), cos(angle));
}
position = uTroikaOrient * position;
normal = uTroikaOrient * normal;
Expand Down Expand Up @@ -215,6 +223,7 @@ export function createTextDerivedMaterial(baseMaterial) {
uTroikaOutlineOpacity: {value: 0},
uTroikaFillOpacity: {value: 1},
uTroikaPositionOffset: {value: new Vector2()},
uTroikaCurveRadius: {value: 0},
uTroikaBlurRadius: {value: 0},
uTroikaStrokeWidth: {value: 0},
uTroikaStrokeColor: {value: new Color()},
Expand Down

0 comments on commit 6fdfbbf

Please sign in to comment.