Browse Source

feat(cientos): Text3D now accepts sweet text via slots

Alvaro 2 years ago
parent
commit
8f3a2f4787

+ 8 - 2
packages/cientos/src/core/Text3D.vue

@@ -2,7 +2,7 @@
 import { WebGLRenderer } from 'three'
 import { TextGeometry, FontLoader } from 'three-stdlib'
 
-import { computed, inject, Ref } from 'vue'
+import { computed, inject, Ref, useSlots } from 'vue'
 import { useCientos } from './useCientos'
 
 type Glyph = {
@@ -55,6 +55,12 @@ 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') {
@@ -85,7 +91,7 @@ const textOptions = computed(() => {
 </script>
 <template>
   <TresMesh v-if="font">
-    <TresTextGeometry :args="[text, textOptions]" />
+    <TresTextGeometry v-if="localText" :args="[localText, textOptions]" />
     <slot />
   </TresMesh>
 </template>

+ 2 - 1
packages/tres/src/App.vue

@@ -28,7 +28,8 @@ useTweakPane()
         <OrbitControls />
         <TresAmbientLight :intensity="0.5" />
         <!--  <TresOrbitControls v-if="state.renderer" :args="[state.camera, state.renderer?.domElement]" /> -->
-        <Text3D text="Awiwi" font="https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json">
+        <Text3D font="https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json">
+          Yeah buddy
           <TresMeshNormalMaterial />
         </Text3D>
         <!--   <TestSphere /> -->

+ 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()