Skip to content
This repository has been archived by the owner on Feb 10, 2023. It is now read-only.

[Feature] 3D text #71

Closed
IRobot1 opened this issue Mar 17, 2022 · 10 comments
Closed

[Feature] 3D text #71

IRobot1 opened this issue Mar 17, 2022 · 10 comments

Comments

@IRobot1
Copy link
Contributor

IRobot1 commented Mar 17, 2022

Code below might be a good candidate for an easy drop-in SOBA 3D Text component.

image

    <ngt-mesh-standard-material #mat1="ngtMeshStandardMaterial" 
        [parameters]="{ color:'#b00000' | color }">
    </ngt-mesh-standard-material>
    <ngt-mesh-standard-material #mat2="ngtMeshStandardMaterial" 
        [parameters]="{ color:'#ff8000' | color }">
     </ngt-mesh-standard-material>

    <text3d [text]="'@angular-three'" [size]="10" [height]="5"
            [fonturl]="fonturl"
            [material]="[mat2.material, mat1.material]"></text3d>
import { Component, Input } from '@angular/core';

import { Box3, Euler, Group, Material, Mesh, MeshBasicMaterial } from 'three';

import { NgtTriplet } from '@angular-three/core';

import { Font, FontLoader, TextGeometry } from 'three-stdlib';

//
// adapted from three.js example https://threejs.org/examples/?q=text#webgl_geometry_text
//
@Component({
  selector: 'text3d',
  template: '<ngt-group #text="ngtGroup" (ready)="ready(text.group)" [position]="position" [scale]="scale" [rotation]="rotation"></ngt-group>'
})
export class Text3DComponent {
  private _text = '';
  @Input()
  get text(): string {
    return this._text;
  }
  set text(newvalue: string) {
    this._text = newvalue;
    if (newvalue && this.font) {
      this.refreshtext()
    }
  }

  //
  // see https://threejs.org/docs/index.html?q=mesh#examples/en/loaders/FontLoader for more details
  //
  private _fonturl = '';
  @Input()
  get fonturl(): string {
    return this._fonturl;
  }
  set fonturl(newvalue: string) {
    if (newvalue && newvalue != this._fonturl) {
      this._fonturl = newvalue;
      const loader = new FontLoader();
      loader.load(newvalue,
        (font) => {
          this.font = font;
          this.refreshtext();
        },
        _ => { }, // progress
        (err) => {
          console.error(err);
        });
    }
  }

  @Input() size = 100;
  @Input() height = 50;
  @Input() curveSegments = 12;
  @Input() bevelEnabled = false;
  @Input() bevelThickness = 10;
  @Input() bevelSize = 8;
  @Input() bevelOffset = 0;

  @Input() position = [0, 0, 0] as NgtTriplet;
  @Input() rotation = new Euler();
  @Input() scale = [1, 1, 1] as NgtTriplet;
  @Input() material: Material | Material[] = new MeshBasicMaterial();

  @Input() center = true;

  private font!: Font;
  private group!: Group;
  private lastmesh!: Mesh;

  ready(group: Group) {
    this.group = group;
  }

  private refreshtext() {
    if (this.lastmesh) {
      this.group.remove(this.lastmesh);
    }
    const textGeo = new TextGeometry(this.text, {
      font: this.font,
      size: this.size,
      height: this.height,
      curveSegments: this.curveSegments,
      bevelEnabled: this.bevelEnabled,
      bevelThickness: this.bevelThickness,
      bevelSize: this.bevelSize,
      bevelOffset: this.bevelOffset,
    });

    let centerOffset = 0;
    if (this.center) {
      textGeo.computeBoundingBox();
      const boundingBox = textGeo.boundingBox ?? new Box3();
      centerOffset = - 0.5 * (boundingBox.max.x - boundingBox.min.x);
    }
    const mesh = new Mesh(textGeo, this.material);
    mesh.position.set(this.position[0] + centerOffset, this.position[1], this.position[2]);
    mesh.rotation.copy(this.rotation);
    mesh.scale.set(this.scale[0], this.scale[1], this.scale[2]);

    this.group.add(mesh);
    this.lastmesh = mesh;
  }
}
@nartc
Copy link
Owner

nartc commented May 2, 2022

@IRobot1 feel free to submit a PR for this in Soba?

@IRobot1
Copy link
Contributor Author

IRobot1 commented May 6, 2022

Does this need to follow the ComponentStore style?

The fonturl refers to a local asset that needs loading. 'assets/helvetiker_regular.typeface.json'

Is there any existing example of loading an asset either in the soba library or by a story?

@IRobot1
Copy link
Contributor Author

IRobot1 commented May 6, 2022

I've been able to answer my own questions. Working towards pull request

@IRobot1
Copy link
Contributor Author

IRobot1 commented May 6, 2022

Can you add some notes to CONTRIBUTING that expands on "Start working on changes".

I was running nx storybook soba and it was working. Now, I can't get it started again. There's so many build errors its impossible to figure out what's wrong. I'm getting very frustrated with this project.

@IRobot1
Copy link
Contributor Author

IRobot1 commented May 6, 2022

ERROR in ./libs/soba/.storybook/manager.js 1:0-43
Module not found: Error: [CaseSensitivePathsPlugin] C:\Users\adria\Source\Repos\angular-three\node_modules\.pnpm\@storybook+addons@6.4.22\node_modules\@storybook\addons\dist\esm\public_api.js does not match the corresponding path on disk repos.

@IRobot1
Copy link
Contributor Author

IRobot1 commented May 6, 2022

npm install got me back to working condition again.
Running pnpm install breaks things.

@nartc
Copy link
Owner

nartc commented May 6, 2022

@IRobot1 Sorry for the frustration. I just cloned the repo to another location and everything works as expected:

  • pnpm install
  • npx nx storybook soba

I would recommend nuking your node_modules, package-lock.json (if you have it), and pnpm-lock.yaml then run pnpm install again. Then try again.

@nartc
Copy link
Owner

nartc commented May 6, 2022

@IRobot1 What's your pnpm version?

@IRobot1
Copy link
Contributor Author

IRobot1 commented May 6, 2022

pnpm version 7.0.0

@nartc
Copy link
Owner

nartc commented May 6, 2022

well yeah me too. Try what I suggested above and let me know if you can progress

@nartc nartc closed this as completed May 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants