diff --git a/src/core/Group.js b/src/core/Group.js index e66f119..42c6bc5 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -1,5 +1,5 @@ import { Group } from 'three'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { inject: { @@ -18,23 +18,30 @@ export default { }; }, created() { + if (!this.$parent) { + console.error('Missing parent'); + } else if (!this.$parent.add || !this.$parent.remove) { + + } + this.parent = this.group ? this.group : this.scene; this.group = new Group(); - useBindProp(this, 'position', this.group.position); - useBindProp(this, 'rotation', this.group.rotation); - useBindProp(this, 'scale', this.group.scale); + bindProp(this, 'position', this.group.position); + bindProp(this, 'rotation', this.group.rotation); + bindProp(this, 'scale', this.group.scale); this.parent.add(this.group); }, unmounted() { - this.parent.remove(this.group); + if (this.$parent) this.$parent.remove(this.group); + }, + methods: { + add(o) { this.group.add(o); }, + remove(o) { this.group.remove(o); }, }, render() { - if (this.$slots.default) { - return this.$slots.default(); - } - return []; + return this.$slots.default ? this.$slots.default() : []; }, __hmrId: 'Group', }; diff --git a/src/core/OrthographicCamera.js b/src/core/OrthographicCamera.js index e433678..7f7006a 100644 --- a/src/core/OrthographicCamera.js +++ b/src/core/OrthographicCamera.js @@ -1,6 +1,6 @@ import { OrthographicCamera, Vector3 } from 'three'; import { watch } from 'vue'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { inject: ['three'], @@ -16,7 +16,7 @@ export default { }, created() { this.camera = new OrthographicCamera(this.left, this.right, this.top, this.bottom, this.near, this.far); - useBindProp(this, 'position', this.camera.position); + bindProp(this, 'position', this.camera.position); ['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'].forEach(p => { watch(() => this[p], () => { diff --git a/src/core/PerspectiveCamera.js b/src/core/PerspectiveCamera.js index 14dc193..be0f8f7 100644 --- a/src/core/PerspectiveCamera.js +++ b/src/core/PerspectiveCamera.js @@ -1,6 +1,6 @@ import { PerspectiveCamera, Vector3 } from 'three'; import { watch } from 'vue'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { inject: ['three'], @@ -14,7 +14,7 @@ export default { }, created() { this.camera = new PerspectiveCamera(this.fov, this.aspect, this.near, this.far); - useBindProp(this, 'position', this.camera.position); + bindProp(this, 'position', this.camera.position); if (this.lookAt) this.camera.lookAt(this.lookAt.x, this.lookAt.y, this.lookAt.z); watch(() => this.lookAt, (v) => { this.camera.lookAt(v.x, v.y, v.z); }, { deep: true }); diff --git a/src/core/Renderer.js b/src/core/Renderer.js index 6cd209a..e164da6 100644 --- a/src/core/Renderer.js +++ b/src/core/Renderer.js @@ -47,7 +47,8 @@ export default { }; if (this.three.init(params)) { - this.three.renderer.shadowMap.enabled = this.shadow; + this.renderer = this.three.renderer; + this.renderer.shadowMap.enabled = this.shadow; if (this.three.composer) this.animateC(); else this.animate(); }; diff --git a/src/core/Scene.js b/src/core/Scene.js index 3bc8965..ac41f4d 100644 --- a/src/core/Scene.js +++ b/src/core/Scene.js @@ -24,12 +24,8 @@ export default { } }, methods: { - // add(o) { - // this.scene.add(o); - // }, - // remove(o) { - // this.scene.remove(o); - // }, + add(o) { this.scene.add(o); }, + remove(o) { this.scene.remove(o); }, }, render() { if (this.$slots.default) { diff --git a/src/effects/TiltShiftPass.js b/src/effects/TiltShiftPass.js index 72d17ff..d636281 100644 --- a/src/effects/TiltShiftPass.js +++ b/src/effects/TiltShiftPass.js @@ -3,7 +3,7 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; import { watch } from 'vue'; import EffectPass from './EffectPass.js'; import TiltShift from '../shaders/TiltShift.js'; -import useBindPropValue from '../use/useBindPropValue.js'; +import { bindPropValue } from '../tools.js'; export default { extends: EffectPass, @@ -28,8 +28,8 @@ export default { uniforms1.end = uniforms.end; uniforms1.texSize = uniforms.texSize; - useBindPropValue(this, 'blurRadius', uniforms.blurRadius); - useBindPropValue(this, 'gradientRadius', uniforms.gradientRadius); + bindPropValue(this, 'blurRadius', uniforms.blurRadius); + bindPropValue(this, 'gradientRadius', uniforms.gradientRadius); this.updateFocusLine(); ['start', 'end'].forEach(p => { diff --git a/src/effects/ZoomBlurPass.js b/src/effects/ZoomBlurPass.js index 2fa7f2a..e7c2022 100644 --- a/src/effects/ZoomBlurPass.js +++ b/src/effects/ZoomBlurPass.js @@ -1,8 +1,7 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; import EffectPass from './EffectPass.js'; import ZoomBlur from '../shaders/ZoomBlur.js'; -import useBindProp from '../use/useBindProp.js'; -import useBindPropValue from '../use/useBindPropValue.js'; +import { bindProp, bindPropValue } from '../tools.js'; export default { extends: EffectPass, @@ -15,8 +14,8 @@ export default { this.passes.push(this.pass); const uniforms = this.uniforms = this.pass.uniforms; - useBindProp(this, 'center', uniforms.center.value); - useBindPropValue(this, 'strength', uniforms.strength); + bindProp(this, 'center', uniforms.center.value); + bindPropValue(this, 'strength', uniforms.strength); }, __hmrId: 'ZoomBlurPass', }; diff --git a/src/lights/Light.js b/src/lights/Light.js index 08e123a..60374e0 100644 --- a/src/lights/Light.js +++ b/src/lights/Light.js @@ -1,7 +1,7 @@ import { Color } from 'three'; import { watch } from 'vue'; import { setFromProp } from '../tools.js'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { inject: { @@ -30,10 +30,10 @@ export default { this.parent = this.group ? this.group : this.scene; }, mounted() { - useBindProp(this, 'position', this.light.position); + bindProp(this, 'position', this.light.position); if (this.light.target) { - useBindProp(this, 'target', this.light.target.position); + bindProp(this, 'target', this.light.target.position); } if (this.light.shadow) { diff --git a/src/materials/StandardMaterial.js b/src/materials/StandardMaterial.js index b6a04cb..d0d7b51 100644 --- a/src/materials/StandardMaterial.js +++ b/src/materials/StandardMaterial.js @@ -1,7 +1,7 @@ import { MeshStandardMaterial, Vector2 } from 'three'; import { watch } from 'vue'; import { propsValues } from '../tools.js'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; import Material from './Material'; const props = { @@ -39,7 +39,7 @@ export default { } }); }); - useBindProp(this, 'normalScale', this.material.normalScale); + bindProp(this, 'normalScale', this.material.normalScale); }, }, __hmrId: 'StandardMaterial', diff --git a/src/meshes/Gem.js b/src/meshes/Gem.js index 74ceaec..e2a89e8 100644 --- a/src/meshes/Gem.js +++ b/src/meshes/Gem.js @@ -9,7 +9,7 @@ import { } from 'three'; // import { watch } from 'vue'; import Mesh from '../meshes/Mesh.js'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { extends: Mesh, @@ -33,7 +33,7 @@ export default { initGem() { const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); - useBindProp(this, 'position', this.cubeCamera.position); + bindProp(this, 'position', this.cubeCamera.position); this.parent.add(this.cubeCamera); this.material.side = FrontSide; @@ -55,9 +55,9 @@ export default { this.meshBack = new TMesh(this.geometry, this.materialBack); - useBindProp(this, 'position', this.meshBack.position); - useBindProp(this, 'rotation', this.meshBack.rotation); - useBindProp(this, 'scale', this.meshBack.scale); + bindProp(this, 'position', this.meshBack.position); + bindProp(this, 'rotation', this.meshBack.rotation); + bindProp(this, 'scale', this.meshBack.scale); this.parent.add(this.meshBack); }, updateCubeRT() { diff --git a/src/meshes/InstancedMesh.js b/src/meshes/InstancedMesh.js index 43d3bc1..a333ac2 100644 --- a/src/meshes/InstancedMesh.js +++ b/src/meshes/InstancedMesh.js @@ -1,6 +1,6 @@ import { InstancedMesh } from 'three'; import { watch } from 'vue'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { inject: { @@ -42,9 +42,9 @@ export default { this.mesh = new InstancedMesh(this.geometry, this.material, this.count); - useBindProp(this, 'position', this.mesh.position); - useBindProp(this, 'rotation', this.mesh.rotation); - useBindProp(this, 'scale', this.mesh.scale); + bindProp(this, 'position', this.mesh.position); + bindProp(this, 'rotation', this.mesh.rotation); + bindProp(this, 'scale', this.mesh.scale); ['castShadow', 'receiveShadow'].forEach(p => { this.mesh[p] = this[p]; diff --git a/src/meshes/Mesh.js b/src/meshes/Mesh.js index 33ca980..5c4ce5d 100644 --- a/src/meshes/Mesh.js +++ b/src/meshes/Mesh.js @@ -1,6 +1,6 @@ import { Mesh } from 'three'; import { watch } from 'vue'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { inject: { @@ -63,9 +63,9 @@ export default { this.$emit('ready'); }, bindProps() { - useBindProp(this, 'position', this.mesh.position); - useBindProp(this, 'rotation', this.mesh.rotation); - useBindProp(this, 'scale', this.mesh.scale); + bindProp(this, 'position', this.mesh.position); + bindProp(this, 'rotation', this.mesh.rotation); + bindProp(this, 'scale', this.mesh.scale); ['castShadow', 'receiveShadow'].forEach(p => { this.mesh[p] = this[p]; diff --git a/src/meshes/MirrorMesh.js b/src/meshes/MirrorMesh.js index 37ff08d..41ff95d 100644 --- a/src/meshes/MirrorMesh.js +++ b/src/meshes/MirrorMesh.js @@ -6,7 +6,7 @@ import { } from 'three'; // import { watch } from 'vue'; import Mesh from './Mesh.js'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { extends: Mesh, diff --git a/src/meshes/RefractionMesh.js b/src/meshes/RefractionMesh.js index 6531c66..b015043 100644 --- a/src/meshes/RefractionMesh.js +++ b/src/meshes/RefractionMesh.js @@ -7,7 +7,7 @@ import { } from 'three'; // import { watch } from 'vue'; import Mesh from './Mesh.js'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { extends: Mesh, @@ -31,7 +31,7 @@ export default { initMirrorMesh() { const cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { mapping: CubeRefractionMapping, format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); - useBindProp(this, 'position', this.cubeCamera.position); + bindProp(this, 'position', this.cubeCamera.position); this.parent.add(this.cubeCamera); this.material.envMap = cubeRT.texture; diff --git a/src/meshes/Sprite.js b/src/meshes/Sprite.js index 9bfac89..e956ec8 100644 --- a/src/meshes/Sprite.js +++ b/src/meshes/Sprite.js @@ -1,5 +1,5 @@ import { Sprite, SpriteMaterial, TextureLoader } from 'three'; -import useBindProp from '../use/useBindProp.js'; +import { bindProp } from '../tools.js'; export default { emits: ['ready', 'loaded'], @@ -21,8 +21,8 @@ export default { this.material = new SpriteMaterial({ map: this.texture }); this.sprite = new Sprite(this.material); this.geometry = this.sprite.geometry; - useBindProp(this, 'position', this.sprite.position); - useBindProp(this, 'scale', this.sprite.scale); + bindProp(this, 'position', this.sprite.position); + bindProp(this, 'scale', this.sprite.scale); this.parent.add(this.sprite); this.$emit('ready'); diff --git a/src/plugin.js b/src/plugin.js index 4b6a529..470e5ab 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -1,3 +1,4 @@ +import { createApp as _createApp } from 'vue'; import * as TROIS from './index.js'; export const TroisJSVuePlugin = { @@ -90,3 +91,7 @@ export const TroisJSVuePlugin = { }); }, }; + +export function createApp(params) { + return _createApp(params).use(TroisJSVuePlugin); +}; diff --git a/src/tools.js b/src/tools.js index 51ca482..c4c25b6 100644 --- a/src/tools.js +++ b/src/tools.js @@ -1,3 +1,5 @@ +import { toRef, watch } from 'vue'; + export function setFromProp(o, prop) { if (prop instanceof Object) { Object.entries(prop).forEach(([key, value]) => { @@ -6,6 +8,21 @@ export function setFromProp(o, prop) { } }; +export function bindProp(comp, prop, object) { + const ref = toRef(comp, prop); + setFromProp(object, ref.value); + watch(ref, () => { + setFromProp(object, ref.value); + }, { deep: true }); +}; + +export function bindPropValue(src, srcProp, dst, dstProp = 'value') { + dst[dstProp] = src[srcProp]; + watch(() => src[srcProp], (value) => { + dst[dstProp] = value; + }); +}; + export function propsValues(props, exclude) { const values = {}; Object.entries(props).forEach(([key, value]) => { diff --git a/src/use/useBindProp.js b/src/use/useBindProp.js deleted file mode 100644 index e49154f..0000000 --- a/src/use/useBindProp.js +++ /dev/null @@ -1,12 +0,0 @@ -import { toRef, watch } from 'vue'; -import { setFromProp } from '../tools.js'; - -export default function useBindProp(comp, prop, object) { - if (comp[prop]) { - const ref = toRef(comp, prop); - setFromProp(object, ref.value); - watch(ref, () => { - setFromProp(object, ref.value); - }, { deep: true }); - } -}; diff --git a/src/use/useBindPropValue.js b/src/use/useBindPropValue.js deleted file mode 100644 index 2650c09..0000000 --- a/src/use/useBindPropValue.js +++ /dev/null @@ -1,10 +0,0 @@ -import { watch } from 'vue'; - -export default function useBindPropValue(src, srcProp, dst, dstProp = 'value') { - if (src[srcProp]) { - dst[dstProp] = src[srcProp]; - watch(() => src[srcProp], (value) => { - dst[dstProp] = value; - }); - } -};