浏览代码

Merge pull request #28 from Tresjs/feature/15-text3d-cientos

feat(cientos): text3d cientos
Alvaro Saburido 2 年之前
父节点
当前提交
e5bef4f38d

+ 97 - 0
packages/cientos/src/core/Text3D.vue

@@ -0,0 +1,97 @@
+<script setup lang="ts">
+import { WebGLRenderer } from 'three'
+import { TextGeometry, FontLoader } from 'three-stdlib'
+
+import { computed, inject, Ref, useSlots } from 'vue'
+import { useCientos } from './useCientos'
+
+type Glyph = {
+  _cachedOutline: string[]
+  ha: number
+  o: string
+}
+
+type FontData = {
+  boundingBox: {
+    yMax: number
+    yMin: number
+  }
+  familyName: string
+  glyphs: {
+    [k: string]: Glyph
+  }
+  resolution: number
+  underlineThickness: number
+}
+
+const props = withDefaults(
+  defineProps<{
+    font: FontData | string
+    text?: string
+    size?: number
+    height?: number
+    curveSegments?: number
+    bevelEnabled?: boolean
+    bevelThickness?: number
+    bevelSize?: number
+    bevelOffset?: number
+    bevelSegments?: number
+  }>(),
+  {
+    size: 0.5,
+    height: 0.2,
+    curveSegments: 5,
+    bevelEnabled: true,
+    bevelThickness: 0.05,
+    bevelSize: 0.02,
+    bevelOffset: 0,
+    bevelSegments: 4,
+  },
+)
+
+const { extend } = useCientos()
+
+extend({ TextGeometry })
+
+const loader = new FontLoader()
+
+const slots = useSlots()
+
+const localText = computed(() => {
+  return props.text || slots.default()?.[0]?.children.trim() || 'TresJS'
+})
+
+const font = await new Promise((resolve, reject) => {
+  try {
+    if (typeof props.font === 'string') {
+      loader.load(props.font, font => {
+        resolve(font)
+      })
+    } else {
+      resolve(props.font)
+    }
+  } catch (error) {
+    reject(console.error('cientos', error))
+  }
+})
+
+const textOptions = computed(() => {
+  return {
+    font: font,
+    size: props.size,
+    height: props.height,
+    curveSegments: props.curveSegments,
+    bevelEnabled: props.bevelEnabled,
+    bevelThickness: props.bevelThickness,
+    bevelSize: props.bevelSize,
+    bevelOffset: props.bevelOffset,
+    bevelSegments: props.bevelSegments,
+  }
+})
+</script>
+<template>
+  <TresMesh v-if="font">
+    <TresTextGeometry v-if="localText" :args="[localText, textOptions]" />
+    <slot />
+  </TresMesh>
+</template>

+ 3 - 1
packages/cientos/src/index.ts

@@ -1,5 +1,7 @@
 import OrbitControls from './core/OrbitControls.vue'
 import { useTweakPane } from './core/useTweakPane'
 import { GLTFModel } from './core/useGLTF/component'
+import Text3D from './core/Text3D.vue'
+
 export * from './core/useGLTF'
-export { OrbitControls, useTweakPane, GLTFModel }
+export { OrbitControls, useTweakPane, GLTFModel, Text3D }

文件差异内容过多而无法显示
+ 0 - 0
packages/tres/public/fonts/Gilroy_ExtraBold_Regular.json


+ 5 - 3
packages/tres/src/App.vue

@@ -1,8 +1,7 @@
 <script setup lang="ts">
 /* import { Color } from 'three' */
-import { useTweakPane, OrbitControls, TransformControls } from '../../cientos/src'
+import { useTweakPane, OrbitControls, Text3D } from '../../cientos/src'
 /* import TestSphere from '/@/components/TestSphere.vue' */
-import Text3D from '/@/components/Text3D.vue'
 /* import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
 import { useTres, useCatalogue } from '/@/core' */
 
@@ -29,7 +28,10 @@ useTweakPane()
         <OrbitControls />
         <TresAmbientLight :intensity="0.5" />
         <!--  <TresOrbitControls v-if="state.renderer" :args="[state.camera, state.renderer?.domElement]" /> -->
-        <Text3D />
+        <Text3D font="https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json">
+          Yeah buddy
+          <TresMeshNormalMaterial />
+        </Text3D>
         <!--   <TestSphere /> -->
         <TresAxesHelper :args="[1]" :visible="false" />
         <TresDirectionalLight :position="[0, 2, 4]" :intensity="2" cast-shadow />

+ 1 - 1
packages/tres/src/components/Text3D.vue

@@ -36,6 +36,6 @@ const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresj
 <template>
   <TresMesh>
     <TresTextGeometry :args="['TresJS', { font, ...fontOptions }]" center />
-    <TresMeshMatcapMaterial :matcap="matcapTexture" />
+    <TresMeshNormalMaterial :matcap="matcapTexture" />
   </TresMesh>
 </template>

+ 7 - 4
packages/tres/src/core/useInstanceCreator/index.ts

@@ -59,11 +59,14 @@ export function useInstanceCreator(prefix: string) {
     })
   }
 
-  function createInstanceFromVNode(vnode: TresVNode): TresInstance | TresInstance[] {
-    const regex = /^Symbol\(Fragment\)$/g
+  function createInstanceFromVNode(vnode: TresVNode): TresInstance | TresInstance[] | undefined {
+    const fragmentRegex = /^Symbol\(Fragment\)$/g
+    const textRegex = /^Symbol\(Text\)$/g
     // Check if the vnode is a Fragment
-    if (regex.test(vnode.type.toString())) {
+    if (fragmentRegex.test(vnode.type.toString())) {
       return vnode.children.map(child => createInstanceFromVNode(child as TresVNode)) as TresInstance[]
+    } else if (textRegex.test(vnode.type.toString())) {
+      return
     } else {
       const vNodeType = ((vnode.type as TresVNodeType).name as string).replace(prefix, '')
       const catalogue = inject<Ref<TresCatalogue>>('catalogue')
@@ -107,7 +110,7 @@ export function useInstanceCreator(prefix: string) {
      */
     if (slots.default && slots?.default()) {
       const internal = slots.default().map((vnode: TresVNode) => createInstanceFromVNode(vnode))
-      return new threeObj(...internal.flat())
+      return new threeObj(...internal.flat().filter(Boolean))
     } else {
       // Creates a new THREE instance, if args is present, spread it on the constructor
       return attrs.args ? new threeObj(...attrs.args) : new threeObj()

部分文件因为文件数量过多而无法显示