diff --git a/src/meshes/Text.ts b/src/meshes/Text.ts new file mode 100644 index 0000000..76a10bb --- /dev/null +++ b/src/meshes/Text.ts @@ -0,0 +1,85 @@ +import { defineComponent, watch } from 'vue' +import { Font, FontLoader, TextGeometry } from 'three' +import Mesh, { MeshSetupInterface } from './Mesh' +import { object3DSetup } from '../core/Object3D' + +interface TextSetupInterface extends MeshSetupInterface { + geometry?: TextGeometry + font?: Font +} + +const props = { + text: { type: String, required: true, default: 'Text' }, + fontSrc: { type: String, required: true }, + size: { type: Number, default: 80 }, + height: { type: Number, default: 5 }, + depth: { type: Number, default: 1 }, + curveSegments: { type: Number, default: 12 }, + bevelEnabled: { type: Boolean, default: false }, + bevelThickness: { type: Number, default: 10 }, + bevelSize: { type: Number, default: 8 }, + bevelOffset: { type: Number, default: 0 }, + bevelSegments: { type: Number, default: 5 }, + align: { type: [Boolean, String], default: false }, +} + +export default defineComponent({ + extends: Mesh, + props, + setup(): TextSetupInterface { + return object3DSetup() + }, + created() { + if (!this.fontSrc) { + console.error('Missing required prop: "font-src"') + return + } + // if (!this.text) { + // console.error('Missing required prop: "text"') + // return + // } + + // add watchers + const watchProps = [ + 'text', 'size', 'height', 'curveSegments', + 'bevelEnabled', 'bevelThickness', 'bevelSize', 'bevelOffset', 'bevelSegments', + 'align', + ] + watchProps.forEach(p => { + // @ts-ignore + watch(() => this[p], () => { + if (this.font) this.refreshGeometry() + }) + }) + + const loader = new FontLoader() + this.loading = true + loader.load(this.fontSrc, (font) => { + this.loading = false + this.font = font + this.createGeometry() + this.initMesh() + }) + }, + methods: { + createGeometry() { + this.geometry = new TextGeometry(this.text, { + // @ts-ignore + font: this.font, + size: this.size, + height: this.height, + depth: this.depth, + curveSegments: this.curveSegments, + bevelEnabled: this.bevelEnabled, + bevelThickness: this.bevelThickness, + bevelSize: this.bevelSize, + bevelOffset: this.bevelOffset, + bevelSegments: this.bevelSegments, + }) + + if (this.align === 'center') { + this.geometry.center() + } + }, + }, +})