Skip to content

Instantly share code, notes, and snippets.

@Jeremboo
Created November 21, 2017 17:20
Show Gist options
  • Save Jeremboo/735d7edc81a820aa29c98b927cda8e14 to your computer and use it in GitHub Desktop.
Save Jeremboo/735d7edc81a820aa29c98b927cda8e14 to your computer and use it in GitHub Desktop.
GLMouseMoveListener to listen if the mouse is on a Mesh
/**
* @author jeremboo https://jeremieboulay.fr
*
* GLMouseMoveListener to listen if the mouse is on a Mesh
*
* Ex:
* - Init
* mouseMoveListener.camera = this.webgl.camera;
* this.mouseMoveListener.start()
* ...
* - Usage
* // this = extended new Mesh()
* mouseMoveListener.add(this, this.handleMouseMove)
* mouseMoveListener.remove(this)
*
*/
import { Raycaster, Vector3 } from 'three'
import { getNormalizedPosFromScreen } from 'core/utils'
import { Loop } from 'core/loop'
class GLMouseMoveListener extends Loop {
constructor () {
super()
this.camera = false
this.raycaster = new Raycaster()
this.normalizedMouseVec = new Vector3()
this.objectsToIntersect = []
// Check the device used
if ('ontouchstart' in (window || navigator.msMaxTouchPoints)) {
this.moveEvent = 'touchmove'
this.handleFunction = this._handleTouchMove.bind(this)
} else {
this.moveEvent = 'mousemove'
this.handleFunction = this._handleMouseMove.bind(this)
}
}
/**
****************
* START / STOP
****************
*/
start () {
if (!this.camera) {
console.error('ERROR: You must set the camera renderer into the class.')
return
}
document.body.addEventListener(this.moveEvent, this.handleFunction)
}
stop () {
document.body.removeEventListener(this.moveEvent, this.handleFunction)
}
/**
****************
* ADD
****************
*/
add (object, listener) {
this.objectsToIntersect.push(object)
super.add(object.uuid, listener)
}
remove (object) {
const idx = this.objectsToIntersect.indexOf(object)
if (idx === -1) return
this.objectsToIntersect.splice(idx, 1)
super.remove(object.uuid)
}
/**
****************
* HANDLE EVENT
****************
*/
_handleMouseMove (e) {
this._handleMove(e.clientX, e.clientY)
}
_handleTouchMove (e) {
this._handleMove(e.touches[0].clientX, e.touches[0].clientY)
}
// PURE FUNCTION
_handleMove (x, y) {
this.normalizedMouseVec = getNormalizedPosFromScreen(x, y)
this.raycaster.setFromCamera(this.normalizedMouseVec, this.camera)
let intersects = this.raycaster.intersectObjects(this.objectsToIntersect)
this.objectsToIntersect.forEach(obj => {
let isIntersected = false
intersects = intersects.filter(intersect => {
if (intersect.object.uuid === obj.uuid) {
obj.handleMouseMove(intersect.uv)
isIntersected = true
return false
}
return true
})
if (!isIntersected && obj.mouseIn) {
obj.mouseOut()
}
})
}
}
const mouseMoveListener = new GLMouseMoveListener()
export default mouseMoveListener
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment