mirror of
https://github.com/troisjs/trois.git
synced 2024-11-24 04:12:02 +08:00
wip : refactor props (#54)
This commit is contained in:
parent
19eaa22fc5
commit
cee01894b9
@ -1,6 +1,6 @@
|
|||||||
import { Object3D, Scene } from 'three'
|
import { Object3D, Scene } from 'three'
|
||||||
import { ComponentPublicInstance, defineComponent, PropType, watch } from 'vue'
|
import { ComponentPublicInstance, defineComponent, PropType, watch } from 'vue'
|
||||||
import { bindOptions, bindProp } from '../tools'
|
import { bindObjectProp, bindProp } from '../tools'
|
||||||
import { RendererInjectionKey, RendererInterface } from './Renderer'
|
import { RendererInjectionKey, RendererInterface } from './Renderer'
|
||||||
import { SceneInjectionKey } from './Scene'
|
import { SceneInjectionKey } from './Scene'
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ export default defineComponent({
|
|||||||
bindProp(this, 'userData', o3d.userData)
|
bindProp(this, 'userData', o3d.userData)
|
||||||
bindProp(this, 'visible', o3d)
|
bindProp(this, 'visible', o3d)
|
||||||
|
|
||||||
bindOptions(o3d, this.props)
|
bindObjectProp(this, 'props', o3d)
|
||||||
|
|
||||||
this.$emit('created', o3d)
|
this.$emit('created', o3d)
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable no-use-before-define */
|
/* eslint-disable no-use-before-define */
|
||||||
import { Camera, NoToneMapping, PCFShadowMap, Scene, WebGLRenderer } from 'three'
|
import { Camera, Scene, WebGLRenderer } from 'three'
|
||||||
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
|
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
|
||||||
import { ComponentPublicInstance, defineComponent, InjectionKey, PropType } from 'vue'
|
import { ComponentPublicInstance, defineComponent, InjectionKey, PropType } from 'vue'
|
||||||
import { bindOptions } from '../tools'
|
import { bindObjectProp } from '../tools'
|
||||||
import { PointerPublicConfigInterface } from './usePointer'
|
import { PointerPublicConfigInterface } from './usePointer'
|
||||||
import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree'
|
import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree'
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ export default defineComponent({
|
|||||||
if (props.height) config.height = parseInt(props.height)
|
if (props.height) config.height = parseInt(props.height)
|
||||||
|
|
||||||
const three = useThree(config)
|
const three = useThree(config)
|
||||||
bindOptions(three.renderer, props.props)
|
bindObjectProp(props, 'props', three.renderer)
|
||||||
|
|
||||||
const renderFn: {(): void} = () => {}
|
const renderFn: {(): void} = () => {}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ComponentPublicInstance, defineComponent, InjectionKey, PropType, watch } from 'vue'
|
import { ComponentPublicInstance, defineComponent, InjectionKey } from 'vue'
|
||||||
import { FrontSide, Material, NormalBlending, Texture } from 'three'
|
import { Material, Texture } from 'three'
|
||||||
import { MeshInjectionKey, MeshInterface } from '../meshes/Mesh'
|
import { MeshInjectionKey, MeshInterface } from '../meshes/Mesh'
|
||||||
import { bindOptions } from '../tools'
|
import { bindObjectProp } from '../tools'
|
||||||
|
|
||||||
export interface MaterialSetupInterface {
|
export interface MaterialSetupInterface {
|
||||||
mesh?: MeshInterface
|
mesh?: MeshInterface
|
||||||
@ -10,7 +10,6 @@ export interface MaterialSetupInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MaterialInterface extends MaterialSetupInterface {
|
export interface MaterialInterface extends MaterialSetupInterface {
|
||||||
setProp(key: string, value: unknown, needsUpdate: boolean): void
|
|
||||||
setTexture(texture: Texture | null, key: string): void
|
setTexture(texture: Texture | null, key: string): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,16 +23,7 @@ export default defineComponent({
|
|||||||
mesh: MeshInjectionKey as symbol,
|
mesh: MeshInjectionKey as symbol,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
color: { type: [String, Number] as PropType<string | number>, default: '#ffffff' },
|
color: { type: String, default: '#ffffff' },
|
||||||
blending: { type: Number, default: NormalBlending },
|
|
||||||
alphaTest: { type: Number, default: 0 },
|
|
||||||
depthTest: { type: Boolean, default: true },
|
|
||||||
depthWrite: { type: Boolean, default: true },
|
|
||||||
fog: { type: Boolean, default: true },
|
|
||||||
opacity: { type: Number, default: 1 },
|
|
||||||
side: { type: Number, default: FrontSide },
|
|
||||||
transparent: Boolean,
|
|
||||||
vertexColors: Boolean,
|
|
||||||
props: { type: Object, default: () => ({}) },
|
props: { type: Object, default: () => ({}) },
|
||||||
},
|
},
|
||||||
setup(): MaterialSetupInterface {
|
setup(): MaterialSetupInterface {
|
||||||
@ -52,38 +42,24 @@ export default defineComponent({
|
|||||||
|
|
||||||
if (this.createMaterial) {
|
if (this.createMaterial) {
|
||||||
this.material = this.createMaterial()
|
this.material = this.createMaterial()
|
||||||
bindOptions(this.material, this.props)
|
bindObjectProp(this, 'props', this.material, this.setProp)
|
||||||
this.mesh.setMaterial(this.material)
|
this.mesh.setMaterial(this.material)
|
||||||
this.addWatchers()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
this.material?.dispose()
|
this.material?.dispose()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setProp(key: string, value: any, needsUpdate = false) {
|
getProps() {
|
||||||
if (this.material) {
|
return { color: this.color, ...this.props }
|
||||||
// @ts-ignore
|
},
|
||||||
this.material[key] = value
|
setProp(dst: any, key: string, value: any, needsUpdate = false) {
|
||||||
this.material.needsUpdate = needsUpdate
|
if (key === 'color') dst[key].set(value)
|
||||||
}
|
else dst[key] = value
|
||||||
|
dst.needsUpdate = needsUpdate
|
||||||
},
|
},
|
||||||
setTexture(texture: Texture | null, key = 'map') {
|
setTexture(texture: Texture | null, key = 'map') {
|
||||||
this.setProp(key, texture, true)
|
this.setProp(this, key, texture, true)
|
||||||
},
|
|
||||||
addWatchers() {
|
|
||||||
['color', 'alphaTest', 'blending', 'depthTest', 'depthWrite', 'fog', 'opacity', 'side', 'transparent'].forEach(p => {
|
|
||||||
// @ts-ignore
|
|
||||||
watch(() => this[p], (value) => {
|
|
||||||
if (p === 'color') {
|
|
||||||
// @ts-ignore
|
|
||||||
this.material.color.set(value)
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
this.material[p] = value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { defineComponent, PropType, watch } from 'vue'
|
import { defineComponent, PropType, watch } from 'vue'
|
||||||
import { ShaderMaterial, Texture, TextureLoader } from 'three'
|
import { ShaderMaterial, Texture, TextureLoader } from 'three'
|
||||||
import { bindOptions } from '../tools'
|
import { bindObjectProp } from '../tools'
|
||||||
import { MaterialInjectionKey, MaterialInterface } from './Material'
|
import { MaterialInjectionKey, MaterialInterface } from './Material'
|
||||||
|
|
||||||
export interface TexureInterface {
|
export interface TexureInterface {
|
||||||
@ -40,7 +40,7 @@ export default defineComponent({
|
|||||||
initTexture() {
|
initTexture() {
|
||||||
if (!this.texture) return
|
if (!this.texture) return
|
||||||
|
|
||||||
bindOptions(this.texture, this.props)
|
bindObjectProp(this, 'props', this.texture)
|
||||||
if (!this.material) return
|
if (!this.material) return
|
||||||
|
|
||||||
this.material.setTexture(this.texture, this.name)
|
this.material.setTexture(this.texture, this.name)
|
||||||
|
25
src/tools.ts
25
src/tools.ts
@ -1,16 +1,29 @@
|
|||||||
import { toRef, watch } from 'vue'
|
import { toRef, watch, WatchStopHandle } from 'vue'
|
||||||
|
|
||||||
export function applyOptions(dst: any, options: Record<string, unknown>): void {
|
type OptionSetter = (dst: any, key: string, value: any) => void
|
||||||
|
|
||||||
|
export function applyObjectProps(
|
||||||
|
dst: any,
|
||||||
|
options: Record<string, unknown>,
|
||||||
|
setter?: OptionSetter
|
||||||
|
): void {
|
||||||
if (options instanceof Object) {
|
if (options instanceof Object) {
|
||||||
Object.entries(options).forEach(([key, value]) => {
|
Object.entries(options).forEach(([key, value]) => {
|
||||||
dst[key] = value
|
if (setter) setter(dst, key, value)
|
||||||
|
else dst[key] = value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bindOptions(dst: any, options: Record<string, unknown>): void {
|
export function bindObjectProp(
|
||||||
applyOptions(dst, options)
|
src: any,
|
||||||
watch(() => options, (value) => { applyOptions(dst, value) }, { deep: true })
|
prop: string,
|
||||||
|
dst: any,
|
||||||
|
setter?: OptionSetter
|
||||||
|
): WatchStopHandle {
|
||||||
|
applyObjectProps(dst, src[prop], setter)
|
||||||
|
const r = toRef(src, prop)
|
||||||
|
return watch(r, (value) => { applyObjectProps(dst, value, setter) })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setFromProp(o: Record<string, unknown>, prop: Record<string, unknown>): void {
|
export function setFromProp(o: Record<string, unknown>, prop: Record<string, unknown>): void {
|
||||||
|
Loading…
Reference in New Issue
Block a user