1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00

wip: simplify useThree

This commit is contained in:
Kevin Levron 2021-04-21 01:10:20 +02:00
parent 973dda4002
commit 9583a24136

View File

@ -3,6 +3,14 @@ import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js' import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import usePointer, { IntersectObject, PointerConfigInterface, PointerInterface } from './usePointer' import usePointer, { IntersectObject, PointerConfigInterface, PointerInterface } from './usePointer'
export interface SizeInterface {
width: number
height: number
wWidth: number
wHeight: number
ratio: number
}
export interface ThreeConfigInterface { export interface ThreeConfigInterface {
canvas?: HTMLCanvasElement canvas?: HTMLCanvasElement
antialias: boolean antialias: boolean
@ -13,38 +21,12 @@ export interface ThreeConfigInterface {
resize: boolean | string resize: boolean | string
width?: number width?: number
height?: number height?: number
onResize?(size: SizeInterface): void
[index:string]: any [index:string]: any
} }
export interface SizeInterface {
width: number
height: number
wWidth: number
wHeight: number
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<T = ThreeEventInterface> = (e: T) => void
type ThreeInitCallbackType = ThreeCallbackType<ThreeInitEventInterface>
type ThreeResizeCallbackType = ThreeCallbackType<ThreeResizeEventInterface>
export interface ThreeInterface { export interface ThreeInterface {
conf: ThreeConfigInterface config: ThreeConfigInterface
renderer: WebGLRenderer renderer: WebGLRenderer
composer?: EffectComposer composer?: EffectComposer
camera?: Camera camera?: Camera
@ -57,9 +39,6 @@ export interface ThreeInterface {
render(): void render(): void
renderC(): void renderC(): void
setSize(width: number, height: number): void setSize(width: number, height: number): void
onAfterInit(cb: ThreeInitCallbackType): void
onAfterResize(cb: ThreeResizeCallbackType): void
offAfterResize(cb: ThreeResizeCallbackType): void
addIntersectObject(o: IntersectObject): void addIntersectObject(o: IntersectObject): void
removeIntersectObject(o: IntersectObject): void removeIntersectObject(o: IntersectObject): void
} }
@ -68,8 +47,8 @@ export interface ThreeInterface {
* Three.js helper * Three.js helper
*/ */
export default function useThree(params: ThreeConfigInterface): ThreeInterface { export default function useThree(params: ThreeConfigInterface): ThreeInterface {
// default conf // default config
const conf: ThreeConfigInterface = { const config: ThreeConfigInterface = {
antialias: true, antialias: true,
alpha: false, alpha: false,
autoClear: true, autoClear: true,
@ -82,7 +61,7 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
if (params) { if (params) {
Object.entries(params).forEach(([key, value]) => { Object.entries(params).forEach(([key, value]) => {
conf[key] = value config[key] = value
}) })
} }
@ -93,25 +72,22 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
ratio: 1, ratio: 1,
} }
// handlers const beforeRenderCallbacks: {(): void}[] = []
const afterInitCallbacks: ThreeInitCallbackType[] = []
let afterResizeCallbacks: ThreeResizeCallbackType[] = []
let beforeRenderCallbacks: {(): void}[] = []
const intersectObjects: IntersectObject[] = [] const intersectObjects: IntersectObject[] = []
const renderer = createRenderer()
// returned object // returned object
const obj: ThreeInterface = { const obj: ThreeInterface = {
conf, config,
renderer: createRenderer(), renderer,
size, size,
init, init,
dispose, dispose,
render, render,
renderC, renderC,
setSize, setSize,
onAfterInit,
onAfterResize, offAfterResize,
addIntersectObject, removeIntersectObject, addIntersectObject, removeIntersectObject,
} }
@ -121,8 +97,8 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
* create WebGLRenderer * create WebGLRenderer
*/ */
function createRenderer(): WebGLRenderer { function createRenderer(): WebGLRenderer {
const renderer = new WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha }) const renderer = new WebGLRenderer({ canvas: config.canvas, antialias: config.antialias, alpha: config.alpha })
renderer.autoClear = conf.autoClear renderer.autoClear = config.autoClear
return renderer return renderer
} }
@ -140,27 +116,27 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
return false return false
} }
if (conf.resize) { if (config.resize) {
onResize() onResize()
window.addEventListener('resize', onResize) window.addEventListener('resize', onResize)
} else if (conf.width && conf.height) { } else if (config.width && config.height) {
setSize(conf.width, conf.height) setSize(config.width, config.height)
} }
initPointer() initPointer()
if (conf.orbitCtrl) { if (config.orbitCtrl) {
obj.cameraCtrl = new OrbitControls(obj.camera, obj.renderer.domElement) const cameraCtrl = new OrbitControls(obj.camera, obj.renderer.domElement)
if (conf.orbitCtrl instanceof Object) { if (config.orbitCtrl instanceof Object) {
Object.entries(conf.orbitCtrl).forEach(([key, value]) => { Object.entries(config.orbitCtrl).forEach(([key, value]) => {
// @ts-ignore // @ts-ignore
obj.cameraCtrl[key] = value cameraCtrl[key] = value
}) })
} }
onBeforeRender(() => { cameraCtrl.update() })
obj.cameraCtrl = cameraCtrl
} }
afterInitCallbacks.forEach(c => c({ type: 'afterinit', three: obj }))
return true return true
} }
@ -174,12 +150,12 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
intersectObjects, intersectObjects,
} }
if (conf.pointer && conf.pointer instanceof Object) { if (config.pointer && config.pointer instanceof Object) {
pointerConf = { ...pointerConf, ...conf.pointer } pointerConf = { ...pointerConf, ...config.pointer }
} }
const pointer = obj.pointer = usePointer(pointerConf) const pointer = obj.pointer = usePointer(pointerConf)
if (conf.pointer || intersectObjects.length) { if (config.pointer || intersectObjects.length) {
pointer.addListeners() pointer.addListeners()
if (pointerConf.intersectMode === 'frame') { if (pointerConf.intersectMode === 'frame') {
onBeforeRender(pointer.intersect) onBeforeRender(pointer.intersect)
@ -187,27 +163,6 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
} }
} }
/**
* add after init callback
*/
function onAfterInit(cb: ThreeInitCallbackType) {
afterInitCallbacks.push(cb)
}
/**
* add after resize callback
*/
function onAfterResize(cb: ThreeResizeCallbackType) {
afterResizeCallbacks.push(cb)
}
/**
* remove after resize callback
*/
function offAfterResize(cb: ThreeResizeCallbackType) {
afterResizeCallbacks = afterResizeCallbacks.filter(c => c !== cb)
}
/** /**
* add before render callback * add before render callback
*/ */
@ -215,18 +170,11 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
beforeRenderCallbacks.push(cb) beforeRenderCallbacks.push(cb)
} }
/**
* remove before render callback
*/
// function offBeforeRender(cb: void) {
// beforeRenderCallbacks = beforeRenderCallbacks.filter(c => c !== cb)
// }
/** /**
* default render * default render
*/ */
function render() { function render() {
if (obj.cameraCtrl) obj.cameraCtrl.update() // if (obj.cameraCtrl) obj.cameraCtrl.update()
beforeRenderCallbacks.forEach(c => c()) beforeRenderCallbacks.forEach(c => c())
obj.renderer!.render(obj.scene!, obj.camera!) obj.renderer!.render(obj.scene!, obj.camera!)
} }
@ -235,7 +183,7 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
* composer render * composer render
*/ */
function renderC() { function renderC() {
if (obj.cameraCtrl) obj.cameraCtrl.update() // if (obj.cameraCtrl) obj.cameraCtrl.update()
beforeRenderCallbacks.forEach(c => c()) beforeRenderCallbacks.forEach(c => c())
obj.composer!.render() obj.composer!.render()
} }
@ -262,7 +210,7 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
intersectObjects.splice(i, 1) intersectObjects.splice(i, 1)
} }
// remove listeners if needed // remove listeners if needed
if (obj.pointer && !conf.pointer && intersectObjects.length === 0) { if (obj.pointer && !config.pointer && intersectObjects.length === 0) {
obj.pointer.removeListeners() obj.pointer.removeListeners()
} }
} }
@ -271,7 +219,7 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
* remove listeners and dispose * remove listeners and dispose
*/ */
function dispose() { function dispose() {
beforeRenderCallbacks = [] // beforeRenderCallbacks = []
window.removeEventListener('resize', onResize) window.removeEventListener('resize', onResize)
if (obj.pointer) obj.pointer.removeListeners() if (obj.pointer) obj.pointer.removeListeners()
if (obj.cameraCtrl) obj.cameraCtrl.dispose() if (obj.cameraCtrl) obj.cameraCtrl.dispose()
@ -282,13 +230,13 @@ export default function useThree(params: ThreeConfigInterface): ThreeInterface {
* resize listener * resize listener
*/ */
function onResize() { function onResize() {
if (conf.resize === 'window') { if (config.resize === 'window') {
setSize(window.innerWidth, window.innerHeight) setSize(window.innerWidth, window.innerHeight)
} else { } else {
const elt = obj.renderer!.domElement.parentNode as Element const elt = obj.renderer!.domElement.parentNode as Element
if (elt) setSize(elt.clientWidth, elt.clientHeight) if (elt) setSize(elt.clientWidth, elt.clientHeight)
} }
afterResizeCallbacks.forEach(c => c({ type: 'resize', three: obj, size })) config.onResize?.(size)
} }
/** /**