Skip to content

Commit 22182b0

Browse files
committed
Improved OrbitControls and added example.
1 parent bdfdf6c commit 22182b0

File tree

3 files changed

+208
-45
lines changed

3 files changed

+208
-45
lines changed

examples/misc_camera_orbit.html

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<title>three.js webgl - orbit camera</title>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
7+
<style>
8+
body {
9+
color: #000;
10+
font-family:Monospace;
11+
font-size:13px;
12+
text-align:center;
13+
font-weight: bold;
14+
15+
background-color: #fff;
16+
margin: 0px;
17+
overflow: hidden;
18+
}
19+
20+
#info {
21+
color:#000;
22+
position: absolute;
23+
top: 0px; width: 100%;
24+
padding: 5px;
25+
26+
}
27+
28+
a {
29+
color: red;
30+
}
31+
</style>
32+
</head>
33+
34+
<body>
35+
<div id="container"></div>
36+
<div id="info">
37+
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - orbit camera example
38+
</div>
39+
40+
<script src="../build/Three.js"></script>
41+
42+
<script src="js/Detector.js"></script>
43+
<script src="js/Stats.js"></script>
44+
45+
<script>
46+
47+
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
48+
49+
var container, stats;
50+
51+
var camera, controls, scene, renderer;
52+
53+
var cross;
54+
55+
init();
56+
animate();
57+
58+
function init() {
59+
60+
// scene and camera
61+
62+
scene = new THREE.Scene();
63+
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
64+
65+
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
66+
camera.position.z = 500;
67+
68+
scene.add( camera );
69+
70+
controls = new THREE.OrbitControls( camera );
71+
controls.addEventListener( 'change', render );
72+
73+
// world
74+
75+
var geometry = new THREE.CylinderGeometry( 0, 10, 30, 4, 1 );
76+
var material = new THREE.MeshLambertMaterial( { color:0xffffff, shading: THREE.FlatShading } );
77+
78+
for ( var i = 0; i < 500; i ++ ) {
79+
80+
var mesh = new THREE.Mesh( geometry, material );
81+
mesh.position.x = ( Math.random() - 0.5 ) * 1000;
82+
mesh.position.y = ( Math.random() - 0.5 ) * 1000;
83+
mesh.position.z = ( Math.random() - 0.5 ) * 1000;
84+
mesh.updateMatrix();
85+
mesh.matrixAutoUpdate = false;
86+
scene.add( mesh );
87+
88+
}
89+
90+
91+
// lights
92+
93+
light = new THREE.DirectionalLight( 0xffffff );
94+
light.position.set( 1, 1, 1 );
95+
scene.add( light );
96+
97+
light = new THREE.DirectionalLight( 0x002288 );
98+
light.position.set( -1, -1, -1 );
99+
scene.add( light );
100+
101+
light = new THREE.AmbientLight( 0x222222 );
102+
scene.add( light );
103+
104+
105+
// renderer
106+
107+
renderer = new THREE.WebGLRenderer( { antialias: false } );
108+
renderer.setClearColor( scene.fog.color, 1 );
109+
renderer.setSize( window.innerWidth, window.innerHeight );
110+
111+
container = document.getElementById( 'container' );
112+
container.appendChild( renderer.domElement );
113+
114+
stats = new Stats();
115+
stats.domElement.style.position = 'absolute';
116+
stats.domElement.style.top = '0px';
117+
stats.domElement.style.zIndex = 100;
118+
container.appendChild( stats.domElement );
119+
120+
}
121+
122+
function animate() {
123+
124+
requestAnimationFrame( animate );
125+
controls.update();
126+
127+
}
128+
129+
function render() {
130+
131+
renderer.render( scene, camera );
132+
stats.update();
133+
134+
}
135+
136+
137+
</script>
138+
139+
</body>
140+
</html>

examples/misc_camera_trackball.html

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,29 @@
55
<meta charset="utf-8">
66
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
77
<style>
8-
body {
9-
color: #000;
10-
font-family:Monospace;
11-
font-size:13px;
12-
text-align:center;
13-
font-weight: bold;
14-
15-
background-color: #fff;
16-
margin: 0px;
17-
overflow: hidden;
18-
}
19-
20-
#info {
21-
color:#000;
22-
position: absolute;
23-
top: 0px; width: 100%;
24-
padding: 5px;
8+
body {
9+
color: #000;
10+
font-family:Monospace;
11+
font-size:13px;
12+
text-align:center;
13+
font-weight: bold;
14+
15+
background-color: #fff;
16+
margin: 0px;
17+
overflow: hidden;
18+
}
2519

26-
}
20+
#info {
21+
color:#000;
22+
position: absolute;
23+
top: 0px; width: 100%;
24+
padding: 5px;
2725

28-
a { color: red; }
26+
}
2927

28+
a {
29+
color: red;
30+
}
3031
</style>
3132
</head>
3233

src/extras/controls/OrbitControls.js

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
/**
22
* @author qiao / https://github.com/qiao
3+
* @author mrdoob / http://mrdoob.com
34
*/
45

5-
THREE.OrbitControls = function( object, domElement ) {
6-
6+
THREE.OrbitControls = function ( object, domElement ) {
7+
8+
THREE.EventTarget.call( this );
9+
710
this.object = object;
8-
this.domElement = ( domElement !== undefined ? domElement : document );
11+
this.domElement = ( domElement !== undefined ) ? domElement : document;
912

1013
// API
1114

12-
this.center = new THREE.Vector3( 0, 0, 0 );
15+
this.center = new THREE.Vector3();
1316

1417
this.userZoom = true;
1518
this.userZoomSpeed = 1.0;
@@ -22,19 +25,26 @@ THREE.OrbitControls = function( object, domElement ) {
2225

2326
// internals
2427

25-
var self = this;
28+
var scope = this;
2629

2730
var EPS = 0.000001;
2831
var PIXELS_PER_ROUND = 1800;
2932

3033
var rotateStart = new THREE.Vector2();
3134
var rotateEnd = new THREE.Vector2();
3235
var rotateDelta = new THREE.Vector2();
33-
var rotating = false;
36+
3437
var phiDelta = 0;
3538
var thetaDelta = 0;
3639
var scale = 1;
3740

41+
var lastPosition = new THREE.Vector3();
42+
43+
// events
44+
45+
var changeEvent = { type: 'change' };
46+
47+
3848
this.rotateLeft = function ( angle ) {
3949

4050
if ( angle === undefined ) {
@@ -142,72 +152,84 @@ THREE.OrbitControls = function( object, domElement ) {
142152
thetaDelta = 0;
143153
phiDelta = 0;
144154
scale = 1;
155+
156+
if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
157+
158+
this.dispatchEvent( changeEvent );
159+
160+
lastPosition.copy( this.object.position );
161+
162+
}
163+
145164
};
146165

147166

148167
function getAutoRotationAngle() {
149168

150-
return 2 * Math.PI / 60 / 60 * self.autoRotateSpeed;
169+
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
151170

152171
}
153172

154173
function getZoomScale() {
155174

156-
return Math.pow( 0.95, self.userZoomSpeed );
175+
return Math.pow( 0.95, scope.userZoomSpeed );
157176

158177
}
159178

160-
function onMouseMove( event ) {
179+
function onMouseDown( event ) {
161180

162-
if ( !rotating ) return;
181+
if ( !scope.userRotate ) return;
163182

164-
rotateEnd.set( event.clientX, event.clientY );
165-
rotateDelta.sub( rotateEnd, rotateStart );
183+
event.preventDefault();
166184

167-
self.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * self.userRotateSpeed );
168-
self.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * self.userRotateSpeed );
185+
rotateStart.set( event.clientX, event.clientY );
169186

170-
rotateStart.copy( rotateEnd );
187+
document.addEventListener( 'mousemove', onMouseMove, false );
188+
document.addEventListener( 'mouseup', onMouseUp, false );
171189

172190
}
173191

174-
function onMouseDown( event ) {
192+
function onMouseMove( event ) {
175193

176-
if ( !self.userRotate ) return;
194+
event.preventDefault();
177195

178-
rotateStart.set( event.clientX, event.clientY );
179-
rotating = true;
196+
rotateEnd.set( event.clientX, event.clientY );
197+
rotateDelta.sub( rotateEnd, rotateStart );
198+
199+
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
200+
scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );
201+
202+
rotateStart.copy( rotateEnd );
180203

181204
}
182205

183206
function onMouseUp( event ) {
184207

185-
if ( !self.userRotate ) return;
208+
if ( ! scope.userRotate ) return;
186209

187-
rotating = false;
210+
document.removeEventListener( 'mousemove', onMouseMove, false );
211+
document.removeEventListener( 'mouseup', onMouseUp, false );
188212

189213
}
190214

191215
function onMouseWheel( event ) {
192216

193-
if ( !self.userZoom ) return;
217+
if ( ! scope.userZoom ) return;
194218

195219
if ( event.wheelDelta > 0 ) {
196220

197-
self.zoomOut();
221+
scope.zoomOut();
198222

199223
} else {
200224

201-
self.zoomIn();
225+
scope.zoomIn();
202226

203227
}
204228

205229
}
206230

207231
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
208-
this.domElement.addEventListener( 'mousemove', onMouseMove, false );
209232
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
210-
this.domElement.addEventListener( 'mouseup', onMouseUp, false );
211233
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
212234

213235
};

0 commit comments

Comments
 (0)