Browse Source

fix: implement createComment and nextSibling node operations so that objects being v-if'd are not lost by Vue's runtime and incorrectly placed in the scene root

Garrett Walker 11 months ago
parent
commit
814d678b62
1 changed files with 37 additions and 4 deletions
  1. 37 4
      src/core/nodeOps.ts

+ 37 - 4
src/core/nodeOps.ts

@@ -1,5 +1,5 @@
 import type { RendererOptions } from 'vue'
-import { BufferAttribute } from 'three'
+import { BufferAttribute, Object3D } from 'three'
 import { isFunction } from '@alvarosabu/utils'
 import type { Camera } from 'three'
 import type { TresContext } from '../composables'
@@ -293,10 +293,43 @@ export const nodeOps: () => RendererOptions<TresObject, TresObject | null> = ()
     }
   }
 
-  function parentNode(node: TresObject) {
+  function parentNode(node: TresObject): TresObject | null {
     return node?.parent || null
   }
 
+  /**
+   * createComment
+   *
+   * Creates a comment object that can be used to represent a commented out string in a vue template
+   * Used by Vue's internal runtime as a placeholder for v-if'd elements
+   *
+   * @param comment Any commented out string contaiend in a vue template, typically this is `v-if`
+   * @returns TresObject
+   */
+  function createComment(comment: string): TresObject {
+    const commentObj = new Object3D() as TresObject
+
+    // Set name and type to comment
+    // TODO: Add a custom type for comments instead of reusing Object3D. Comments should be light weight and not exist in the scene graph
+    commentObj.name = comment
+    commentObj.__tres = { type: 'Comment' }
+
+    // Without this we have errors in other nodeOp functions that come across this object
+    commentObj.__tres.root = scene?.__tres.root as TresContext
+
+    return commentObj
+  }
+
+  // nextSibling - Returns the next sibling of a TresObject
+  function nextSibling(node: TresObject) {
+    if (!node) { return null }
+
+    const parent = node.parent || scene
+    const index = parent.children.indexOf(node)
+
+    return parent.children[index + 1] || null
+  }
+
   return {
     insert,
     remove,
@@ -304,10 +337,10 @@ export const nodeOps: () => RendererOptions<TresObject, TresObject | null> = ()
     patchProp,
     parentNode,
     createText: () => noop('createText'),
-    createComment: () => noop('createComment'),
+    createComment,
     setText: () => noop('setText'),
     setElementText: () => noop('setElementText'),
-    nextSibling: () => noop('nextSibling'),
+    nextSibling,
     querySelector: () => noop('querySelector'),
     setScopeId: () => noop('setScopeId'),
     cloneNode: () => noop('cloneNode'),