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