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:
parent
973dda4002
commit
9583a24136
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user