Selaa lähdekoodia

feat(cientos): typed and story

Alvaro 2 vuotta sitten
vanhempi
commit
851baf937c

+ 2 - 6
.eslintrc.js

@@ -7,12 +7,7 @@ module.exports = {
   },
   parser: 'vue-eslint-parser',
   plugins: ['vue', '@typescript-eslint'],
-  extends: [
-    'eslint:recommended',
-    'plugin:@typescript-eslint/recommended',
-    'plugin:vue/vue3-recommended',
-    'prettier',
-  ],
+  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:vue/vue3-recommended', 'prettier'],
   parserOptions: {
     tsconfigRootDir: __dirname,
     parser: '@typescript-eslint/parser',
@@ -37,5 +32,6 @@ module.exports = {
     'vue/multi-word-component-names': 0,
     'vue/no-multiple-template-root': 'off',
     'vue/first-attribute-linebreak': 'off',
+    'vue/setup-compiler-macros': true,
   },
 }

+ 61 - 10
packages/cientos/src/core/TransformControls.vue

@@ -1,34 +1,85 @@
 <script setup lang="ts">
-/* import { useRenderLoop } from '@tresjs/core' */
 import { Camera, Object3D, Scene, WebGLRenderer } from 'three'
 import { TransformControls as TransformControlsImp } from 'three-stdlib'
-import { inject, type Ref, unref, watch, useSlots } from 'vue'
+import { inject, computed, type Ref, unref, watch, shallowRef, ShallowRef } from 'vue'
+import { pick } from '../utils'
 
-let controls: TransformControlsImp
+const props = withDefaults(
+  defineProps<{
+    object: Object3D
+    mode?: string
+    enabled?: boolean
+    axis?: 'X' | 'Y' | 'Z' | 'XY' | 'YZ' | 'XZ' | 'XYZ'
+    translationSnap?: number
+    rotationSnap?: number
+    scaleSnap?: number
+    space?: 'local' | 'world'
+    size?: number
+    showX?: boolean
+    showY?: boolean
+    showZ?: boolean
+  }>(),
+  {
+    enabled: true,
+  },
+)
+
+let controls: ShallowRef<TransformControlsImp | undefined> = shallowRef()
 
-const props = defineProps<{
-  object: Ref<Object3D>
-  mode: 'translate' | 'rotate' | 'scale' | 'scaleUniform'
-}>()
+const transformOnlyProps = [
+  'enabled',
+  'axis',
+  'mode',
+  'translationSnap',
+  'rotationSnap',
+  'scaleSnap',
+  'space',
+  'size',
+  'showX',
+  'showY',
+  'showZ',
+]
 
 const camera = inject<Ref<Camera>>('camera')
 const renderer = inject<Ref<WebGLRenderer>>('renderer')
 const scene = inject<Ref<Scene>>('local-scene')
 
+const transformProps = computed(() => pick(props, transformOnlyProps))
+
 watch(
   [camera, renderer],
   () => {
     if (camera?.value && renderer?.value && scene?.value) {
-      controls = new TransformControlsImp(camera.value, unref(renderer).domElement)
+      controls.value = new TransformControlsImp(camera.value, unref(renderer).domElement)
 
-      controls.attach(unref(props.object))
-      scene.value.add(controls)
+      controls.value.attach(unref(props.object))
+      scene.value.add(unref(controls) as TransformControlsImp)
     }
   },
   {
     deep: true,
   },
 )
+
+watch(
+  [transformProps, controls],
+  // TODO: properly type this
+  ([value, controlsValue]: [any, any]) => {
+    console.log([value, controlsValue])
+    if (value && controlsValue) {
+      for (const key in value) {
+        const methodName = `set${key[0].toUpperCase()}${key.slice(1)}`
+
+        if (typeof controlsValue[methodName] === 'function' && value[key] !== undefined) {
+          ;(controlsValue[methodName] as (param: any) => void)(value[key])
+        }
+      }
+    }
+  },
+  {
+    immediate: true,
+  },
+)
 </script>
 <template>
   <slot />

+ 11 - 0
packages/cientos/src/utils/index.ts

@@ -0,0 +1,11 @@
+export function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
+  const result: Partial<T> = {}
+
+  for (const key of keys) {
+    if (key in obj) {
+      result[key] = obj[key]
+    }
+  }
+
+  return result as Pick<T, K>
+}

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

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { Color, Object3D } from 'three'
 import { ref } from 'vue'
-import { useTweakPane, TransformControls } from '../../cientos/src'
+import { useTweakPane, TransformControls } from '@tresjs/cientos'
 import TestSphere from '/@/components/TestSphere.vue'
 
 const sphereRef = ref<Object3D>()

+ 31 - 0
packages/tres/src/examples/cientos/controls/TransformControls.story.vue

@@ -0,0 +1,31 @@
+<script setup lang="ts">
+import { TransformControls } from '@tresjs/cientos'
+/* import { TransformControls, useTweakPane } from '../../../../../cientos/src' */
+import { reactive, ref } from 'vue'
+
+const boxRef = ref()
+</script>
+<template>
+  <Story title="cientos/controls/TransformControls">
+    <Variant title="playground">
+      <TresCanvas clear-color="#82DBC5" shadows alpha>
+        <TresPerspectiveCamera
+          :position="[5, 5, 5]"
+          :look-at="[0, 0, 0]"
+          :fov="45"
+          :aspect="1"
+          :near="0.1"
+          :far="1000"
+        />
+        <TresScene>
+          <TransformControls :object="boxRef" />
+          <TresMesh ref="boxRef" cast-shadow>
+            <TresBoxGeometry :args="[1.5, 1.5, 1.5]" />
+            <TresMeshToonMaterial color="#4F4F4F" />
+          </TresMesh>
+          <TresDirectionalLight :position="[0, 8, 4]" :intensity="0.7" cast-shadow />
+        </TresScene>
+      </TresCanvas>
+    </Variant>
+  </Story>
+</template>