diff --git a/.eslintrc.js b/.eslintrc.js index 0a0effc..122358c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -51,6 +51,6 @@ module.exports = { 'vue/no-multiple-template-root': 'off', 'no-empty-function': 'off', - '@typescript-eslint/no-empty-function': ['warn'], + '@typescript-eslint/no-empty-function': ['off'], }, } diff --git a/src/core/Object3D.ts b/src/core/Object3D.ts index 3a10ba0..e901c72 100644 --- a/src/core/Object3D.ts +++ b/src/core/Object3D.ts @@ -7,6 +7,13 @@ interface Object3DSetupInterface { parent?: ComponentPublicInstance } +export interface Object3DInterface extends Object3DSetupInterface { + addToParent(o?: Object3D): boolean + removeFromParent(o?: Object3D): boolean + add(o: Object3D): void + remove(o: Object3D): void +} + export default defineComponent({ name: 'Object3D', inject: ['three', 'scene', 'renderer'], diff --git a/src/core/Renderer.ts b/src/core/Renderer.ts index 4893226..822cf77 100644 --- a/src/core/Renderer.ts +++ b/src/core/Renderer.ts @@ -35,9 +35,6 @@ export interface RendererInterface extends RendererSetupInterface { offAfterRender(cb: CallbackType>): void } -// type MountedCallbackType = CallbackType> -// type RenderCallbackType = CallbackType> - export default defineComponent({ name: 'Renderer', props: { diff --git a/src/core/useThree.ts b/src/core/useThree.ts index dffe90e..2fcfa79 100644 --- a/src/core/useThree.ts +++ b/src/core/useThree.ts @@ -24,6 +24,25 @@ export interface SizeInterface { ratio: number } +export interface ThreeEventInterface { + type: 'afterinit' | 'resize' + // eslint-disable-next-line no-use-before-define + three: ThreeInterface +} + +export interface ThreeInitEventInterface extends ThreeEventInterface { + type: 'afterinit' +} + +export interface ThreeResizeEventInterface extends ThreeEventInterface { + type: 'resize' + size: SizeInterface +} + +type ThreeCallbackType = (e: T) => void +type ThreeInitCallbackType = ThreeCallbackType +type ThreeResizeCallbackType = ThreeCallbackType + export interface ThreeInterface { conf: ThreeConfigInterface renderer: WebGLRenderer @@ -38,9 +57,9 @@ export interface ThreeInterface { render(): void renderC(): void setSize(width: number, height: number): void - onAfterInit(callback: {(): void}): void - onAfterResize(callback: {(): void}): void - offAfterResize(callback: {(): void}): void + onAfterInit(cb: ThreeInitCallbackType): void + onAfterResize(cb: ThreeResizeCallbackType): void + offAfterResize(cb: ThreeResizeCallbackType): void addIntersectObject(o: IntersectObject): void removeIntersectObject(o: IntersectObject): void } @@ -75,8 +94,8 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface { } // handlers - const afterInitCallbacks: {(): void}[] = [] - let afterResizeCallbacks: {(): void}[] = [] + const afterInitCallbacks: ThreeInitCallbackType[] = [] + let afterResizeCallbacks: ThreeResizeCallbackType[] = [] let beforeRenderCallbacks: {(): void}[] = [] const intersectObjects: IntersectObject[] = [] @@ -140,7 +159,7 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface { } } - afterInitCallbacks.forEach(c => c()) + afterInitCallbacks.forEach(c => c({ type: 'afterinit', three: obj })) return true } @@ -171,36 +190,36 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface { /** * add after init callback */ - function onAfterInit(callback: {(): void}) { - afterInitCallbacks.push(callback) + function onAfterInit(cb: ThreeInitCallbackType) { + afterInitCallbacks.push(cb) } /** * add after resize callback */ - function onAfterResize(callback: {(): void}) { - afterResizeCallbacks.push(callback) + function onAfterResize(cb: ThreeResizeCallbackType) { + afterResizeCallbacks.push(cb) } /** * remove after resize callback */ - function offAfterResize(callback: {(): void}) { - afterResizeCallbacks = afterResizeCallbacks.filter(c => c !== callback) + function offAfterResize(cb: ThreeResizeCallbackType) { + afterResizeCallbacks = afterResizeCallbacks.filter(c => c !== cb) } /** * add before render callback */ - function onBeforeRender(callback: {(): void}) { - beforeRenderCallbacks.push(callback) + function onBeforeRender(cb: {(): void}) { + beforeRenderCallbacks.push(cb) } /** * remove before render callback */ - // function offBeforeRender(callback: void) { - // beforeRenderCallbacks = beforeRenderCallbacks.filter(c => c !== callback) + // function offBeforeRender(cb: void) { + // beforeRenderCallbacks = beforeRenderCallbacks.filter(c => c !== cb) // } /** @@ -269,7 +288,7 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface { const elt = obj.renderer!.domElement.parentNode as Element if (elt) setSize(elt.clientWidth, elt.clientHeight) } - afterResizeCallbacks.forEach(c => c()) + afterResizeCallbacks.forEach(c => c({ type: 'resize', three: obj, size })) } /** diff --git a/src/effects/TiltShiftPass.ts b/src/effects/TiltShiftPass.ts new file mode 100644 index 0000000..38fe6cf --- /dev/null +++ b/src/effects/TiltShiftPass.ts @@ -0,0 +1,64 @@ +import { defineComponent, watch } from 'vue' +import { ShaderMaterial, Vector2 } from 'three' +import { Pass } from 'three/examples/jsm/postprocessing/Pass' +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js' +import EffectPass from './EffectPass' +import TiltShift from '../shaders/TiltShift' +import { bindProp } from '../tools' + +const props = { + blurRadius: { type: Number, default: 10 }, + gradientRadius: { type: Number, default: 100 }, + start: { type: Object, default: () => ({ x: 0, y: 100 }) }, + end: { type: Object, default: () => ({ x: 10, y: 100 }) }, +} + +interface TiltShiftPassSetupInterface { + uniforms: {[name: string]: { value: any }} + pass1?: Pass + pass2?: Pass +} + +export default defineComponent({ + extends: EffectPass, + props, + setup(): TiltShiftPassSetupInterface { + const uniforms = {} + return { uniforms } + }, + created() { + const shaderMat = new ShaderMaterial(TiltShift) + this.uniforms = shaderMat.uniforms + + this.pass1 = new ShaderPass(shaderMat) + this.pass2 = new ShaderPass(shaderMat) + + bindProp(this, 'blurRadius', this.uniforms.blurRadius, 'value') + bindProp(this, 'gradientRadius', this.uniforms.gradientRadius, 'value') + this.updateFocusLine(); + + ['start', 'end'].forEach(p => { + // @ts-ignore + watch(() => this[p], this.updateFocusLine, { deep: true }) + }) + + this.pass1.setSize = (width: number, height: number) => { + this.uniforms.texSize.value.set(width, height) + } + + this.initEffectPass(this.pass1) + this.composer.addPass(this.pass2) + }, + unmounted() { + if (this.pass2) this.composer.removePass(this.pass2) + }, + methods: { + updateFocusLine() { + this.uniforms.start.value.copy(this.start) + this.uniforms.end.value.copy(this.end) + const dv = new Vector2().copy(this.end as Vector2).sub(this.start as Vector2).normalize() + this.uniforms.delta.value.copy(dv) + }, + }, + __hmrId: 'TiltShiftPass', +}) diff --git a/src/export.js b/src/export.js deleted file mode 100644 index e8cba66..0000000 --- a/src/export.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from './index.js'; -export * from './plugin.js'; diff --git a/src/export.ts b/src/export.ts new file mode 100644 index 0000000..d9f6aa0 --- /dev/null +++ b/src/export.ts @@ -0,0 +1,2 @@ +export * from './index' +export * from './plugin' diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 87dd77d..0000000 --- a/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export * from './core/index.js'; -export * from './geometries/index.js'; -export * from './lights/index.js'; -export * from './materials/index.js'; -export * from './meshes/index.js'; -export * from './models/index.js'; -export * from './effects/index.js'; - -// export * from './components/index.js'; - -export * from './tools'; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..7087925 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,11 @@ +export * from './core/index' +export * from './geometries/index' +export * from './lights/index' +export * from './materials/index' +export * from './meshes/index' +export * from './models/index' +export * from './effects/index' + +// export * from './components/index' + +export * from './tools' diff --git a/src/lights/Light.ts b/src/lights/Light.ts index 4fc024b..46cfd48 100644 --- a/src/lights/Light.ts +++ b/src/lights/Light.ts @@ -1,4 +1,4 @@ -import { DirectionalLight, Light, LightShadow, SpotLight } from 'three' +import { DirectionalLight, Light, SpotLight } from 'three' import { defineComponent, watch } from 'vue' import Object3D from '../core/Object3D' import { bindProp, setFromProp } from '../tools' @@ -29,7 +29,7 @@ export default defineComponent({ initLight(light: Light) { this.light = light - if (light instanceof LightShadow) { + if ((light as any).shadow) { light.castShadow = this.castShadow // @ts-ignore setFromProp(light.shadow.mapSize, this.shadowMapSize) diff --git a/src/plugin.ts b/src/plugin.ts index a7d7f60..334e668 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,8 +1,8 @@ -import { createApp as _createApp } from 'vue'; -import * as TROIS from './index.js'; +import { App, createApp as _createApp } from 'vue' +import * as TROIS from './index' export const TroisJSVuePlugin = { - install: (app) => { + install(app: App): void { const comps = [ 'Camera', 'OrthographicCamera', @@ -73,14 +73,14 @@ export const TroisJSVuePlugin = { 'ZoomBlurPass', 'GLTFViewer', - ]; + ] comps.forEach(comp => { - app.component(comp, TROIS[comp]); - }); + app.component(comp, TROIS[comp]) + }) }, -}; +} -export function createApp(params) { - return _createApp(params).use(TroisJSVuePlugin); -}; +export function createApp(params: any): App { + return _createApp(params).use(TroisJSVuePlugin) +} diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts new file mode 100644 index 0000000..ac1ded7 --- /dev/null +++ b/src/shims-vue.d.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +}