Created
January 8, 2017 14:58
-
-
Save macrozone/5d6b08289c45e17399ce6caf55dc6ed2 to your computer and use it in GitHub Desktop.
react-three extended scene
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Scene } from 'react-three'; | |
import THREE from 'three'; | |
import _ from 'lodash'; | |
/** | |
we extend the react-three-scene with support for more properties: | |
- onOrbit: will be called when orbitcontrols are changed. It will pass the current camera | |
- onClickRay: will be called on a click on the scene with arguments: | |
event, the current ray from the camera to the mousePosition and the mousePosition | |
- onMouseMoveRay: same as above, but on every mousemove | |
**/ | |
// Scene is not a real class, so we do some other approach of inheritance: | |
const superBindOrbitControls = Scene.prototype.bindOrbitControls; | |
Scene.prototype.bindOrbitControls = function (inst, canvas, props) { | |
superBindOrbitControls.call(this, inst, canvas, props); | |
if (this._THREEMetaData.orbitControls) { | |
this._THREEMetaData.orbitControls.addEventListener('change', () => { | |
this._THREEMetaData.orbitControlsIsChanging = true; | |
if (_.isFunction(this._currentElement.props.onOrbit)) { | |
this._currentElement.props.onOrbit(this._THREEMetaData.camera); | |
} | |
}); | |
this._THREEMetaData.orbitControls.addEventListener('end', _.debounce(() => { | |
// wait a bit | |
this._THREEMetaData.orbitControlsIsChanging = false; | |
}), 300); | |
} | |
}; | |
// we override the original function completly, because it tries to raycast to every child | |
// which leads to bad performance | |
Scene.prototype.projectPointerEvent = function (event, eventName, canvas) { | |
if (this._THREEMetaData.orbitControlsIsChanging) { | |
return; // prevent pointer events if orbit is rotating | |
} | |
event.preventDefault(); | |
var rect = canvas.getBoundingClientRect(); | |
const {clientX, clientY} = event.touches ? event.touches[0] : event; | |
var x = ( (clientX - rect.left) / rect.width) * 2 - 1; | |
var y = -( (clientY - rect.top) / rect.height) * 2 + 1; | |
var mousecoords = new THREE.Vector3(x,y,0.5); | |
let { raycaster, camera } = this._THREEMetaData; | |
raycaster.setFromCamera(mousecoords, camera); | |
if (eventName === 'onClick') { | |
if (_.isFunction(this._currentElement.props.onClickRay)) { | |
this._currentElement.props.onClickRay(event, raycaster.ray, {x,y}); | |
} | |
} | |
if (eventName === 'onMouseMove') { | |
if (_.isFunction(this._currentElement.props.onMouseMoveRay)) { | |
this._currentElement.props.onMouseMoveRay(event, raycaster.ray, {x,y}); | |
} | |
} | |
}; | |
export default Scene; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment