Skip to content

Instantly share code, notes, and snippets.

@para-dise
Created July 12, 2020 18:01
Show Gist options
  • Save para-dise/2d4c404e3d5f570fe26183877415a215 to your computer and use it in GitHub Desktop.
Save para-dise/2d4c404e3d5f570fe26183877415a215 to your computer and use it in GitHub Desktop.
Object drag rotation in Three.js
<div class="caption">Drag to rotate</div>
/**
* Provides requestAnimationFrame in a cross browser way.
* @author paulirish / http://paulirish.com/
*/
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (function() {
return window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
window.setTimeout(callback, 1000 / 60);
};
})();
}
var container, stats;
var camera, scene, renderer;
var cube, plane;
var targetRotationX = 0.5;
var targetRotationOnMouseDownX = 0;
var targetRotationY = 0.2;
var targetRotationOnMouseDownY = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var mouseY = 0;
var mouseYOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var slowingFactor = 0.25;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
scene.add( camera );
var materials = [];
for ( var i = 0; i < 6; i ++ ) {
materials.push( new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
}
cube = new THREE.Mesh( new THREE.BoxGeometry( 200, 200, 200 ) , new THREE.MeshFaceMaterial(materials) );
cube.position.y = 150;
cube.overdraw = true;
scene.add( cube );
plane = new THREE.Mesh( new THREE.PlaneGeometry( 200, 200 ), new THREE.MeshBasicMaterial( { color: 0xe0e0e0 } ) );
plane.rotation.x = - 90 * ( Math.PI / 180 );
plane.overdraw = true;
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDownX = targetRotationX;
mouseYOnMouseDown = event.clientY - windowHalfY;
targetRotationOnMouseDownY = targetRotationY;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
targetRotationX = ( mouseX - mouseXOnMouseDown ) * 0.00025;
mouseY = event.clientY - windowHalfY;
targetRotationY = ( mouseY - mouseYOnMouseDown ) * 0.00025;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
rotateAroundWorldAxis(cube, new THREE.Vector3(0, 1, 0), targetRotationX);
rotateAroundWorldAxis(cube, new THREE.Vector3(1, 0, 0), targetRotationY);
targetRotationY = targetRotationY * (1 - slowingFactor);
targetRotationX = targetRotationX * (1 - slowingFactor);
renderer.render( scene, camera );
}
function rotateAroundObjectAxis(object, axis, radians) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis(axis.normalize(), radians);
object.matrix.multiply(rotationMatrix);
object.rotation.setFromRotationMatrix( object.matrix );
}
function rotateAroundWorldAxis( object, axis, radians ) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis( axis.normalize(), radians );
rotationMatrix.multiply( object.matrix ); // pre-multiply
object.matrix = rotationMatrix;
object.rotation.setFromRotationMatrix( object.matrix );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r11/Stats.min.js"></script>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
.caption{
padding: 1rem;
color: white;
background: black;
font-size: 2rem;
text-align:center;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment