diff --git a/src/core/Renderer.vue b/src/core/Renderer.vue index 298b70d..44a7479 100644 --- a/src/core/Renderer.vue +++ b/src/core/Renderer.vue @@ -26,7 +26,7 @@ export default { default: false, }, mouseMove: { - type: Boolean, + type: [Boolean, String], default: false, }, mouseRaycast: { @@ -43,7 +43,6 @@ export default { setup(props) { return { three: useThree(), - beforeRender: [], raf: true, }; }, @@ -72,17 +71,17 @@ export default { }, beforeUnmount() { this.raf = false; - this.beforeRender.splice(0); this.three.dispose(); }, methods: { onBeforeRender(callback) { - this.beforeRender.push(callback); + this.three.onBeforeRender(callback); + }, + onAfterResize(callback) { + this.three.onAfterResize(callback); }, - onAfterResize() {}, animate() { if (this.raf) requestAnimationFrame(this.animate); - this.beforeRender.forEach(c => c()); this.three.render(); }, }, diff --git a/src/core/useThree.js b/src/core/useThree.js index 58bd1a1..2a2c9f0 100644 --- a/src/core/useThree.js +++ b/src/core/useThree.js @@ -32,6 +32,10 @@ export default function useThree() { ratio: 0, }; + // handlers + const afterResizeHandlers = []; + const beforeRenderHandlers = []; + // mouse tracking const mouse = new Vector2(); const mouseV3 = new Vector3(); @@ -52,6 +56,8 @@ export default function useThree() { dispose, render, setSize, + onAfterResize, + onBeforeRender, }; /** @@ -64,8 +70,6 @@ export default function useThree() { } } - obj.renderer = new WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha }); - if (!obj.scene) { console.error('Missing Scene'); return; @@ -76,6 +80,8 @@ export default function useThree() { return; } + obj.renderer = new WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha }); + if (conf.orbit_ctrl) { obj.orbitCtrl = new OrbitControls(obj.camera, obj.renderer.domElement); if (conf.orbit_ctrl instanceof Object) { @@ -93,8 +99,13 @@ export default function useThree() { } if (conf.mouse_move) { - obj.renderer.domElement.addEventListener('mousemove', onMousemove); - obj.renderer.domElement.addEventListener('mouseleave', onMouseleave); + if (conf.mouse_move === 'body') { + obj.mouse_move_element = document.body; + } else { + obj.mouse_move_element = obj.renderer.domElement; + } + obj.mouse_move_element.addEventListener('mousemove', onMousemove); + obj.mouse_move_element.addEventListener('mouseleave', onMouseleave); } return obj; @@ -105,16 +116,26 @@ export default function useThree() { */ function render() { if (obj.orbitCtrl) obj.orbitCtrl.update(); + beforeRenderHandlers.forEach(c => c()); obj.renderer.render(obj.scene, obj.camera); } + /** + * add before render handler + */ + function onBeforeRender(callback) { + beforeRenderHandlers.push(callback); + } + /** * remove listeners */ function dispose() { window.removeEventListener('resize', onResize); - obj.renderer.domElement.removeEventListener('mousemove', onMousemove); - obj.renderer.domElement.removeEventListener('mouseleave', onMouseleave); + if (obj.mouse_move_element) { + obj.mouse_move_element.removeEventListener('mousemove', onMousemove); + obj.mouse_move_element.removeEventListener('mouseleave', onMouseleave); + } } /** @@ -156,6 +177,14 @@ export default function useThree() { } else { setSize(conf.resize.clientWidth, conf.resize.clientHeight); } + afterResizeHandlers.forEach(c => c()); + } + + /** + * add after resize handler + */ + function onAfterResize(callback) { + afterResizeHandlers.push(callback); } /**