diff --git a/src/core/README.md b/src/core/README.md index b815e41..ba82129 100644 --- a/src/core/README.md +++ b/src/core/README.md @@ -1,7 +1,7 @@ ## TODO - [X] Document raycaster component - [X] Document new events/props on Object3D -- [ ] Click events on Raycaster +- [X] Click events on Raycaster - [X] Click events on Object3D ## Changelog @@ -17,6 +17,7 @@ See [here](https://troisjs-instancedcolors.netlify.app/) for an example ([source :onPointerOver="callback that accepts an array of all new intersections, like onMouseEnter" :onPointerLeave="callback that accepts an array of all newly-ended intersections, like onMouseLeave" :onPointerOver="callback that accepts array of all current intersections" + :onClick="callback that accepts array of currently intersected objects" :onBeforeRender="callback that fires every frame - optional, accepts the created raycaster. setting this property assumes the user is implementing all raycaster functionality and nullifies all other props and built-in functionality." :scene="THREE scene - optional, defaults to current scene" diff --git a/src/core/Raycaster.js b/src/core/Raycaster.js index 1c06d45..3f5f9a1 100644 --- a/src/core/Raycaster.js +++ b/src/core/Raycaster.js @@ -20,6 +20,10 @@ export default { type: Function, default: null }, + onClick: { + type: Function, + default: null + }, scene: { type: Object, default: null @@ -71,6 +75,9 @@ export default { // add event listeners window.addEventListener('mousemove', this.onMouseMove); window.addEventListener('touchmove', this.onTouchMove); + if (this.onClick) { + window.addEventListener('click', this.clickHandler); + } // TODO: touch }, methods: { @@ -106,7 +113,7 @@ export default { // TODO: optimize const expiredIntersects = this._intersects.filter(intersect => !newObjects.find(val => val.object === intersect.object && val.instanceId === intersect.instanceId)); if (expiredIntersects.length) { - this.onPointerLeave(expiredIntersects) + this.onPointerLeave(expiredIntersects); } } @@ -138,6 +145,12 @@ export default { this.pointer.x = ((evt.x - canvasLeft) / this.three.size.width) * 2 - 1; this.pointer.y = - ((evt.y - canvasTop) / this.three.size.height) * 2 + 1; }, + clickHandler(evt) { + // if we have any intersects, fire onclick method + if (this._intersects && this._intersects.length) { + this.onClick(this._intersects); + } + } }, render() { return this.$slots.default ? this.$slots.default() : []; @@ -145,6 +158,7 @@ export default { unmounted() { window.removeEventListener('mousemove', this.onMouseMove); window.removeEventListener('touchstart', this.onTouchMove); + window.removeEventListener('click', this.clickHandler); // TODO: touch },