Pārlūkot izejas kodu

DragControls: Add support for dragging a group object.

Mugen87 5 gadi atpakaļ
vecāks
revīzija
6e03702107

+ 11 - 0
docs/examples/en/controls/DragControls.html

@@ -91,6 +91,12 @@ controls.addEventListener( 'dragend', function ( event ) {
 			Whether or not the controls are enabled.
 		</p>
 
+		<h3>[property:Boolean transformGroup]</h3>
+		<p>
+			This option only works if the [page:DragControls.objects] array contains a single draggable group object. 
+			If set to *true*, [name] does not transform individual objects but the entire group. Default is *false*.
+		</p>
+
 		<h2>Methods</h2>
 
 		<p>See the base [page:EventDispatcher] class for common methods.</p>
@@ -110,6 +116,11 @@ controls.addEventListener( 'dragend', function ( event ) {
 			Should be called if the controls is no longer required.
 		</p>
 
+		<h3>[method:Array getObjects] ()</h3>
+		<p>
+			Returns the array of draggable objects.
+		</p>
+
 		<h2>Source</h2>
 
 		<p>

+ 11 - 0
docs/examples/zh/controls/DragControls.html

@@ -91,6 +91,12 @@ controls.addEventListener( 'dragend', function ( event ) {
 			Whether or not the controls are enabled.
 		</p>
 
+		<h3>[property:Boolean transformGroup]</h3>
+		<p>
+			This option only works if the [page:DragControls.objects] array contains a single draggable group object.
+			If set to *true*, [name] does not transform individual objects but the entire group. Default is *false*.
+		</p>
+
 		<h2>Methods</h2>
 
 		<p>See the base [page:EventDispatcher] class for common methods.</p>
@@ -110,6 +116,11 @@ controls.addEventListener( 'dragend', function ( event ) {
 			Should be called if the controls is no longer required.
 		</p>
 
+		<h3>[method:Array getObjects] ()</h3>
+		<p>
+			Returns the array of draggable objects.
+		</p>
+
 		<h2>Source</h2>
 
 		<p>

+ 10 - 2
examples/js/controls/DragControls.js

@@ -52,6 +52,12 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 	}
 
+	function getObjects() {
+
+		return _objects;
+
+	}
+
 	function onDocumentMouseMove( event ) {
 
 		event.preventDefault();
@@ -123,7 +129,7 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 		if ( _intersections.length > 0 ) {
 
-			_selected = _intersections[ 0 ].object;
+			_selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object;
 
 			if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
@@ -202,7 +208,7 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 		if ( _intersections.length > 0 ) {
 
-			_selected = _intersections[ 0 ].object;
+			_selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object;
 
 			_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
@@ -243,10 +249,12 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 	// API
 
 	this.enabled = true;
+	this.transformGroup = false;
 
 	this.activate = activate;
 	this.deactivate = deactivate;
 	this.dispose = dispose;
+	this.getObjects = getObjects;
 
 };
 

+ 2 - 0
examples/jsm/controls/DragControls.d.ts

@@ -13,9 +13,11 @@ export class DragControls extends EventDispatcher {
 	// API
 
 	enabled: boolean;
+	transformGroup: boolean;
 
 	activate(): void;
 	deactivate(): void;
 	dispose(): void;
+	getObjects(): Object3D[];
 
 }

+ 10 - 2
examples/jsm/controls/DragControls.js

@@ -61,6 +61,12 @@ var DragControls = function ( _objects, _camera, _domElement ) {
 
 	}
 
+	function getObjects() {
+
+		return _objects;
+
+	}
+
 	function onDocumentMouseMove( event ) {
 
 		event.preventDefault();
@@ -132,7 +138,7 @@ var DragControls = function ( _objects, _camera, _domElement ) {
 
 		if ( _intersections.length > 0 ) {
 
-			_selected = _intersections[ 0 ].object;
+			_selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object;
 
 			if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
@@ -211,7 +217,7 @@ var DragControls = function ( _objects, _camera, _domElement ) {
 
 		if ( _intersections.length > 0 ) {
 
-			_selected = _intersections[ 0 ].object;
+			_selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object;
 
 			_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
@@ -252,10 +258,12 @@ var DragControls = function ( _objects, _camera, _domElement ) {
 	// API
 
 	this.enabled = true;
+	this.transformGroup = false;
 
 	this.activate = activate;
 	this.deactivate = deactivate;
 	this.dispose = dispose;
+	this.getObjects = getObjects;
 
 };
 

+ 70 - 24
examples/misc_controls_drag.html

@@ -18,23 +18,25 @@
 	<body>
 
 		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - drag controls
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - drag controls<br />
+			Use "Shift+Click" to add/remove objects to a group. This mode enables group dragging.
 		</div>
 
 		<script type="module">
 
 			import * as THREE from '../build/three.module.js';
 
-			import Stats from './jsm/libs/stats.module.js';
-
 			import { DragControls } from './jsm/controls/DragControls.js';
 
-			var container, stats;
+			var container;
 			var camera, scene, renderer;
+			var controls, group;
 			var objects = [];
+			var enableSelection = false;
+
+			var mouse = new THREE.Vector2(), raycaster = new THREE.Raycaster();
 
 			init();
-			animate();
 
 			function init() {
 
@@ -61,6 +63,9 @@
 
 				scene.add( light );
 
+				group = new THREE.Group();
+				scene.add( group );
+
 				var geometry = new THREE.BoxBufferGeometry( 40, 40, 40 );
 
 				for ( var i = 0; i < 200; i ++ ) {
@@ -97,46 +102,87 @@
 
 				container.appendChild( renderer.domElement );
 
-				var controls = new DragControls( objects, camera, renderer.domElement );
+				controls = new DragControls( [ ... objects ], camera, renderer.domElement );
+				controls.addEventListener( 'drag', render );
 
-				controls.addEventListener( 'dragstart', function ( event ) {
+				//
 
-					event.object.material.emissive.set( 0xaaaaaa );
+				window.addEventListener( 'resize', onWindowResize, false );
 
-				} );
+				document.addEventListener( 'click', onClick, false );
+				window.addEventListener( 'keydown', onKeyDown, false );
+				window.addEventListener( 'keyup', onKeyUp, false );
 
-				controls.addEventListener( 'dragend', function ( event ) {
+				render();
 
-					event.object.material.emissive.set( 0x000000 );
+			}
 
-				} );
+			function onWindowResize() {
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
 
-				//
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
-				window.addEventListener( 'resize', onWindowResize, false );
+				render();
 
 			}
 
-			function onWindowResize() {
+			function onKeyDown( event ) {
 
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
+				enableSelection = ( event.keyCode === 16 ) ? true : false;
 
-				renderer.setSize( window.innerWidth, window.innerHeight );
+			}
+
+			function onKeyUp() {
+
+				enableSelection = false;
 
 			}
 
-			//
+			function onClick( event ) {
+
+				event.preventDefault();
+
+				if ( enableSelection === true ) {
+
+					var draggableObjects = controls.getObjects();
+					draggableObjects.length = 0;
+
+					mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
+					mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
+
+					raycaster.setFromCamera( mouse, camera );
+
+					var intersections = raycaster.intersectObjects( objects, true );
 
-			function animate() {
+					if ( intersections.length > 0 ) {
 
-				requestAnimationFrame( animate );
+						var object = intersections[ 0 ].object;
+						object.material.emissive.set( 0xaaaaaa );
+						group.attach( object );
+
+						controls.transformGroup = true;
+						draggableObjects.push( group );
+
+					} else {
+
+						for ( var i = group.children.length - 1; i >= 0; i -- ) {
+
+							var object = group.children[ i ];
+							object.material.emissive.set( 0x000000 );
+							scene.attach( object );
+
+						}
+
+						controls.transformGroup = false;
+						draggableObjects.push( ...objects );
+
+					}
+
+				}
 
 				render();
-				stats.update();
 
 			}