Răsfoiți Sursa

fix: `nodeOps` is now a function (#579)

* fix: `nodeOps` is now a function

* chore(test): updated tests for `nodeOps`
Alvaro Saburido 1 an în urmă
părinte
comite
ddc229e6e4

+ 0 - 97
playground/src/components/MultipleCanvas.vue

@@ -1,97 +0,0 @@
-<script setup lang="ts">
-import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'
-import { TresCanvas } from '@tresjs/core'
-
-// import { GLTFModel, OrbitControls } from '@tresjs/cientos'
-const state = reactive({
-  clearColor: '#201919',
-  shadows: true,
-  alpha: false,
-  shadowMapType: BasicShadowMap,
-  outputColorSpace: SRGBColorSpace,
-  toneMapping: NoToneMapping,
-  disableRender: false,
-  stencil: false,
-})
-const state2 = reactive({
-  clearColor: '#4f4f4f',
-  shadows: true,
-  alpha: false,
-  /*  shadowMapType: BasicShadowMap,
-  outputColorSpace: SRGBColorSpace,
-  toneMapping: NoToneMapping, */
-})
-const log = () => {
-  console.log(3)
-}
-</script>
-
-<template>
-  <div class="flex">
-    <input
-      id=""
-      v-model="state.clearColor"
-      type="text"
-      name=""
-    >
-    <input
-      v-model="state.stencil"
-      type="checkbox"
-      name=""
-    >
-    <div class="w-1/2 aspect-video">
-      <TresCanvas v-bind="state">
-        <TresPerspectiveCamera
-          :position="[5, 5, 5]"
-          :fov="45"
-          :near="0.1"
-          :far="1000"
-          :look-at="[0, 4, 0]"
-        />
-
-        <TresAmbientLight :intensity="0.5" />
-        <TresMesh
-          :position="[0, 4, 0]"
-          @click="log"
-        >
-          <TresBoxGeometry :args="[1, 1, 1]" />
-          <TresMeshToonMaterial color="cyan" />
-        </TresMesh>
-
-        <Suspense>
-          <TestSphere />
-        </Suspense>
-        <TresDirectionalLight
-          :position="[0, 2, 4]"
-          :intensity="1"
-        />
-      </TresCanvas>
-    </div>
-    <div class="w-1/2 aspect-video">
-      <TresCanvas v-bind="state2">
-        <TresPerspectiveCamera
-          :position="[5, 5, 5]"
-          :fov="45"
-          :near="0.1"
-          :far="1000"
-          :look-at="[0, 4, 0]"
-        />
-        <TresAmbientLight :intensity="0.5" />
-
-        <TresMesh
-          :position="[0, 4, 0]"
-          cast-shadow
-        >
-          <TresSphereGeometry :args="[2, 32, 32]" />
-          <TresMeshToonMaterial color="yellow" />
-        </TresMesh>
-
-        <TresDirectionalLight
-          :position="[0, 2, 4]"
-          :intensity="1"
-          cast-shadow
-        />
-      </TresCanvas>
-    </div>
-  </div>
-</template>

+ 77 - 4
playground/src/pages/multiple.vue

@@ -1,7 +1,80 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { TresCanvas, useRenderLoop } from '@tresjs/core'
+import { reactive, shallowRef, ref } from 'vue'
+import { BasicShadowMap, SRGBColorSpace, NoToneMapping } from 'three'
+import { OrbitControls } from '@tresjs/cientos'
+
+const state = reactive({
+  clearColor: '#82DBC5',
+  shadows: true,
+  alpha: false,
+  shadowMapType: BasicShadowMap,
+  outputColorSpace: SRGBColorSpace,
+  toneMapping: NoToneMapping,
+})
+
+const { onLoop } = useRenderLoop()
+
+const boxRef = shallowRef(null)
+const showBox = ref(true)
+
+/* onLoop(({ elapsed }) => {
+  if (boxRef.value) {
+    boxRef.value.rotation.y = elapsed
+    boxRef.value.rotation.z = elapsed
+  }
+}) */
+
+setInterval(() => {
+  showBox.value = !showBox.value
+}, 3000)
+</script>
 
 <template>
-  <Suspense>
-    <MultipleCanvas />
-  </Suspense>
+  <div class="grid grid-cols-2">
+    <div class="aspect-video">
+      <TresCanvas clear-color="#fff">
+        <TresPerspectiveCamera
+          :position="[5, 5, 5]"
+          :look-at="[0, 0, 0]"
+        />
+
+        <TresAmbientLight
+          :intensity="0.5"
+          color="red"
+        />
+        <TresMesh
+          v-if="showBox"
+          ref="boxRef"
+          :position="[0, 2, 0]"
+        >
+          <TresBoxGeometry :args="[1, 1, 1]" />
+          <TresMeshNormalMaterial />
+        </TresMesh>
+        <TresDirectionalLight
+          :position="[0, 2, 4]"
+          :intensity="1"
+          cast-shadow
+        />
+        <TresAxesHelper />
+        <TresGridHelper :args="[10, 10, 0x444444, 'teal']" />
+      </TresCanvas>
+    </div>
+    <div class="aspect-video">
+      <TresCanvas clear-color="#000">
+        <TresPerspectiveCamera
+          :position="[5, 5, 5]"
+          :look-at="[0, 0, 0]"
+        />
+        <TresMesh>
+          <TresSphereGeometry :args="[1, 32, 32]" />
+          <TresMeshNormalMaterial />
+        </TresMesh>
+        <TresAmbientLight
+          :intensity="0.5"
+          color="red"
+        />
+      </TresCanvas>
+    </div>
+  </div>
 </template>

+ 8 - 3
src/components/TresCanvas.vue

@@ -6,8 +6,8 @@ import type {
   ShadowMapType,
   ToneMapping,
 } from 'three'
-import type { Ref,
-  App } from 'vue'
+import * as THREE from 'three'
+import type { Ref, App } from 'vue'
 import {
   computed,
   onMounted,
@@ -20,6 +20,7 @@ import {
   defineComponent,
   h, 
   getCurrentInstance,
+  createRenderer,
 } from 'vue'
 import pkg from '../../package.json'
 import {
@@ -29,7 +30,7 @@ import {
   type TresContext,
 } from '../composables'
 import { extend } from '../core/catalogue'
-import { render } from '../core/renderer'
+import { nodeOps } from '../core/nodeOps'
 
 import type { RendererPresetsType } from '../composables/useRenderer/const'
 import type { TresCamera, TresObject } from '../types/'
@@ -87,6 +88,7 @@ const slots = defineSlots<{
 }>()
 
 const instance = getCurrentInstance()?.appContext.app
+extend(THREE)
 
 const createInternalComponent = (context: TresContext) =>
   defineComponent({
@@ -105,6 +107,9 @@ const createInternalComponent = (context: TresContext) =>
 
 const mountCustomRenderer = (context: TresContext) => {
   const InternalComponent = createInternalComponent(context)
+
+  const { render } = createRenderer(nodeOps())
+
   render(h(InternalComponent), scene.value as unknown as TresObject)
 }
 

+ 4 - 4
src/core/nodeOps.ts

@@ -12,7 +12,6 @@ function noop(fn: string): any {
   fn
 }
 
-let scene: TresScene | null = null
 const { logError } = useLogger()
 
 const supportedPointerEvents = [
@@ -33,8 +32,9 @@ export function invalidateInstance(instance: TresObject) {
 
 }
 
-export const nodeOps: RendererOptions<TresObject, TresObject | null> = {
-  createElement(tag, _isSVG, _anchor, props): TresObject | null {
+export const nodeOps: () => RendererOptions<TresObject, TresObject | null> = () => {
+  let scene: TresScene | null = null
+  return { createElement(tag, _isSVG, _anchor, props): TresObject | null {
     if (!props) props = {}
 
     if (!props.args) {
@@ -303,5 +303,5 @@ export const nodeOps: RendererOptions<TresObject, TresObject | null> = {
   setScopeId: () => noop('setScopeId'),
   cloneNode: () => noop('cloneNode'),
 
-  insertStaticContent: () => noop('insertStaticContent'),
+  insertStaticContent: () => noop('insertStaticContent') }
 }

+ 13 - 13
src/core/nodeOpts.test.ts

@@ -15,7 +15,7 @@ describe('nodeOps', () => {
     const props = { args: [] }
 
     // Test
-    const instance = nodeOps.createElement(tag, false, null, props)
+    const instance = nodeOps().createElement(tag, false, null, props)
 
     // Assert
     expect(instance.isObject3D).toBeTruthy()
@@ -28,7 +28,7 @@ describe('nodeOps', () => {
     const props = { args: [10, 3, 16, 100] }
 
     // Test
-    const instance = nodeOps.createElement(tag, false, null, props)
+    const instance = nodeOps().createElement(tag, false, null, props)
 
     // Assert
     expect(instance.parameters.radius).toBe(10)
@@ -43,7 +43,7 @@ describe('nodeOps', () => {
     const props = { args: [75, 2, 0.1, 5] }
 
     // Test
-    const instance = nodeOps.createElement(tag, false, null, props)
+    const instance = nodeOps().createElement(tag, false, null, props)
 
     // Assert
     expect(instance.isCamera).toBeTruthy()
@@ -60,7 +60,7 @@ describe('nodeOps', () => {
     consoleWarnSpy.mockImplementation(() => { })
 
     // Test
-    const instance = nodeOps.createElement(tag, false, null, props)
+    const instance = nodeOps().createElement(tag, false, null, props)
 
     // Assert
     expect(instance.isCamera).toBeTruthy()
@@ -74,7 +74,7 @@ describe('nodeOps', () => {
     const props = { args: [] }
 
     // Test
-    const instance = nodeOps.createElement(tag, false, null, props)
+    const instance = nodeOps().createElement(tag, false, null, props)
 
     // Assert
     expect(instance.isMaterial).toBeTruthy()
@@ -87,7 +87,7 @@ describe('nodeOps', () => {
     const props = { args: [] }
 
     // Test
-    const instance = nodeOps.createElement(tag, false, null, props)
+    const instance = nodeOps().createElement(tag, false, null, props)
 
     // Assert
     expect(instance.isBufferGeometry).toBeTruthy()
@@ -115,7 +115,7 @@ describe('nodeOps', () => {
     }
 
     // Test
-    nodeOps.insert(child, parent, null)
+    nodeOps().insert(child, parent, null)
 
     // Assert
     expect(parent.children.includes(child)).toBeTruthy()
@@ -130,10 +130,10 @@ describe('nodeOps', () => {
     child.__vnode = {
       type: 'TresMesh',
     }
-    nodeOps.insert(child, parent)
+    nodeOps().insert(child, parent)
 
     // Test
-    nodeOps.remove(child)
+    nodeOps().remove(child)
 
     // Assert
     expect(!parent.children.includes(child)).toBeTruthy()
@@ -151,7 +151,7 @@ describe('nodeOps', () => {
     const nextValue = false
 
     // Test
-    nodeOps.patchProp(node, prop, null, nextValue)
+    nodeOps().patchProp(node, prop, null, nextValue)
 
     // Assert
     expect(node.visible === nextValue)
@@ -169,7 +169,7 @@ describe('nodeOps', () => {
     const nextValue = 5
 
     // Test
-    nodeOps.patchProp(node, prop, null, nextValue)
+    nodeOps().patchProp(node, prop, null, nextValue)
 
     // Assert
     expect(node.position.x === nextValue)
@@ -187,7 +187,7 @@ describe('nodeOps', () => {
     const nextValue = true
 
     // Test
-    nodeOps.patchProp(node, prop, null, nextValue)
+    nodeOps().patchProp(node, prop, null, nextValue)
 
     // Assert
     expect(node.castShadow === nextValue)
@@ -201,7 +201,7 @@ describe('nodeOps', () => {
     child.parent = parent
 
     // Test
-    const parentNode = nodeOps.parentNode(child)
+    const parentNode = nodeOps().parentNode(child)
 
     // Assert
     expect(parentNode === parent)

+ 0 - 12
src/core/renderer.ts

@@ -1,12 +0,0 @@
-import * as THREE from 'three'
-
-import { createRenderer } from 'vue'
-import { extend } from './catalogue'
-import { nodeOps } from './nodeOps'
-
-export const { render } = createRenderer(nodeOps)
-
-// Creates the catalogue of components based on THREE namespace
-extend(THREE)
-
-export default { extend }