PageSourceSearch

https://ifurniture.la/js/threejs/OrbitControls.js

js ifurniture.la collected 2026-10-09 21:29:03 UTC 7,772 bytes, 362 lines download raw bytes

1/**
2 * @author qiao / https://github.com/qiao
3 * @author mrdoob / http://mrdoob.com
4 * @author alteredq / http://alteredqualia.com/
5 * @author WestLangley / http://github.com/WestLangley
6 */
7
8THREE.OrbitControls = function ( object, domElement ) {
9
10	this.object = object;
11	this.domElement = ( domElement !== undefined ) ? domElement : document;
12
13	// API
14
15	this.enabled = true;
16
17	this.center = new THREE.Vector3();
18
19	this.userZoom = true;
20	this.userZoomSpeed = 1.0;
21
22	this.userRotate = true;
23	this.userRotateSpeed = 1.0;
24
25	this.userPan = true;
26	this.userPanSpeed = 2.0;
27
28	this.autoRotate = false;
29	this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
30
31	this.minPolarAngle = 0; // radians
32	this.maxPolarAngle = Math.PI; // radians
33
34	this.minDistance = 0;
35	this.maxDistance = Infinity;
36
37	this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
38	this.mouseButtons = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; // Añadido para compatibilidad
39
40	// internals
41
42	var scope = this;
43
44	var EPS = 0.000001;
45	var PIXELS_PER_ROUND = 1800;
46
47	var rotateStart = new THREE.Vector2();
48	var rotateEnd = new THREE.Vector2();
49	var rotateDelta = new THREE.Vector2();
50
51	var zoomStart = new THREE.Vector2();
52	var zoomEnd = new THREE.Vector2();
53	var zoomDelta = new THREE.Vector2();
54
55	var phiDelta = 0;
56	var thetaDelta = 0;
57	var scale = 1;
58
59	var lastPosition = new THREE.Vector3();
60
61	var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2 };
62	var state = STATE.NONE;
63
64	// events
65
66	var changeEvent = { type: 'change' };
67
68
69	this.rotateLeft = function ( angle ) {
70
71		if ( angle === undefined ) {
72
73			angle = getAutoRotationAngle();
74
75		}
76
77		thetaDelta -= angle;
78
79	};
80
81	this.rotateRight = function ( angle ) {
82
83		if ( angle === undefined ) {
84
85			angle = getAutoRotationAngle();
86
87		}
88
89		thetaDelta += angle;
90
91	};
92
93	this.rotateUp = function ( angle ) {
94
95		if ( angle === undefined ) {
96
97			angle = getAutoRotationAngle();
98
99		}
100
101		phiDelta -= angle;
102
103	};
104
105	this.rotateDown = function ( angle ) {
106
107		if ( angle === undefined ) {
108
109			angle = getAutoRotationAngle();
110
111		}
112
113		phiDelta += angle;
114
115	};
116
117	this.zoomIn = function ( zoomScale ) {
118
119		if ( zoomScale === undefined ) {
120
121			zoomScale = getZoomScale();
122
123		}
124
125		scale /= zoomScale;
126
127	};
128
129	this.zoomOut = function ( zoomScale ) {
130
131		if ( zoomScale === undefined ) {
132
133			zoomScale = getZoomScale();
134
135		}
136
137		scale *= zoomScale;
138
139	};
140
141	this.pan = function ( distance ) {
142
143		distance.transformDirection( this.object.matrix );
144		distance.multiplyScalar( scope.userPanSpeed );
145
146		this.object.position.add( distance );
147		this.center.add( distance );
148
149	};
150
151	this.update = function () {
152
153		var position = this.object.position;
154		var offset = position.clone().sub( this.center );
155
156		// angle from z-axis around y-axis
157
158		var theta = Math.atan2( offset.x, offset.z );
159
160		// angle from y-axis
161
162		var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
163
164		if ( this.autoRotate ) {
165
166			this.rotateLeft( getAutoRotationAngle() );
167
168		}
169
170		theta += thetaDelta;
171		phi += phiDelta;
172
173		// restrict phi to be between desired limits
174		phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
175
176		// restrict phi to be betwee EPS and PI-EPS
177		phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
178
179		var radius = offset.length() * scale;
180
181		// restrict radius to be between desired limits
182		radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
183
184		offset.x = radius * Math.sin( phi ) * Math.sin( theta );
185		offset.y = radius * Math.cos( phi );
186		offset.z = radius * Math.sin( phi ) * Math.cos( theta );
187
188		position.copy( this.center ).add( offset );
189
190		this.object.lookAt( this.center );
191
192		thetaDelta = 0;
193		phiDelta = 0;
194		scale = 1;
195
196		if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
197
198			this.dispatchEvent( changeEvent );
199
200			lastPosition.copy( this.object.position );
201
202		}
203
204	};
205
206
207	function getAutoRotationAngle() {
208
209		return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
210
211	}
212
213	function getZoomScale() {
214
215		return Math.pow( 0.95, scope.userZoomSpeed );
216
217	}
218
219	function onMouseDown( event ) {
220
221		if ( scope.enabled === false ) return;
222
223		event.preventDefault();
224
225		var buttonMode = -1;
226		if ( event.button === 0 ) buttonMode = (scope.mouseButtons.LEFT !== undefined) ? scope.mouseButtons.LEFT : STATE.ROTATE;
227		else if ( event.button === 1 ) buttonMode = (scope.mouseButtons.MIDDLE !== undefined) ? scope.mouseButtons.MIDDLE : STATE.ZOOM;
228		else if ( event.button === 2 ) buttonMode = (scope.mouseButtons.RIGHT !== undefined) ? scope.mouseButtons.RIGHT : STATE.PAN;
229
230		if ( buttonMode === STATE.ROTATE && scope.userRotate ) {
231			state = STATE.ROTATE;
232			rotateStart.set( event.clientX, event.clientY );
233		} else if ( buttonMode === STATE.ZOOM && scope.userZoom ) {
234			state = STATE.ZOOM;
235			zoomStart.set( event.clientX, event.clientY );
236		} else if ( buttonMode === STATE.PAN && scope.userPan ) {
237			state = STATE.PAN;
238			// No logic for pan start here in this old version, but it checks in move
239		}
240
241		document.addEventListener( 'mousemove', onMouseMove, false );
242		document.addEventListener( 'mouseup', onMouseUp, false );
243
244	}
245
246	function onMouseMove( event ) {
247
248		if ( scope.enabled === false ) return;
249
250		event.preventDefault();
251
252		if ( state === STATE.ROTATE ) {
253
254			rotateEnd.set( event.clientX, event.clientY );
255			rotateDelta.subVectors( rotateEnd, rotateStart );
256
257			scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
258			scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );
259
260			rotateStart.copy( rotateEnd );
261
262		} else if ( state === STATE.ZOOM ) {
263
264			zoomEnd.set( event.clientX, event.clientY );
265			zoomDelta.subVectors( zoomEnd, zoomStart );
266
267			if ( zoomDelta.y > 0 ) {
268
269				scope.zoomIn();
270
271			} else {
272
273				scope.zoomOut();
274
275			}
276
277			zoomStart.copy( zoomEnd );
278
279		} else if ( state === STATE.PAN ) {
280
281			var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
282			var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
283
284			scope.pan( new THREE.Vector3( - movementX, movementY, 0 ) );
285
286		}
287
288	}
289
290	function onMouseUp( event ) {
291
292		if ( scope.enabled === false ) return;
293		if ( scope.userRotate === false ) return;
294
295		document.removeEventListener( 'mousemove', onMouseMove, false );
296		document.removeEventListener( 'mouseup', onMouseUp, false );
297
298		state = STATE.NONE;
299
300	}
301
302	function onMouseWheel( event ) {
303
304		if ( scope.enabled === false ) return;
305		if ( scope.userZoom === false ) return;
306
307		var delta = 0;
308
309		if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
310
311			delta = event.wheelDelta;
312
313		} else if ( event.detail ) { // Firefox
314
315			delta = - event.detail;
316
317		}
318
319		if ( delta > 0 ) {
320
321			scope.zoomOut();
322
323		} else {
324
325			scope.zoomIn();
326
327		}
328
329	}
330
331	function onKeyDown( event ) {
332
333		if ( scope.enabled === false ) return;
334		if ( scope.userPan === false ) return;
335
336		switch ( event.keyCode ) {
337
338			case scope.keys.UP:
339				scope.pan( new THREE.Vector3( 0, 1, 0 ) );
340				break;
341			case scope.keys.BOTTOM:
342				scope.pan( new THREE.Vector3( 0, - 1, 0 ) );
343				break;
344			case scope.keys.LEFT:
345				scope.pan( new THREE.Vector3( - 1, 0, 0 ) );
346				break;
347			case scope.keys.RIGHT:
348				scope.pan( new THREE.Vector3( 1, 0, 0 ) );
349				break;
350		}
351
352	}
353
354	this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
355	this.domElement.addEventListener( 'mousedown', onMouseDown, false );
356	this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
357	this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
358	this.domElement.addEventListener( 'keydown', onKeyDown, false );
359
360};
361
362THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.