|
@@ -18,23 +18,25 @@
|
|
<body>
|
|
<body>
|
|
|
|
|
|
<div id="info">
|
|
<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>
|
|
</div>
|
|
|
|
|
|
<script type="module">
|
|
<script type="module">
|
|
|
|
|
|
import * as THREE from '../build/three.module.js';
|
|
import * as THREE from '../build/three.module.js';
|
|
|
|
|
|
- import Stats from './jsm/libs/stats.module.js';
|
|
|
|
-
|
|
|
|
import { DragControls } from './jsm/controls/DragControls.js';
|
|
import { DragControls } from './jsm/controls/DragControls.js';
|
|
|
|
|
|
- var container, stats;
|
|
|
|
|
|
+ var container;
|
|
var camera, scene, renderer;
|
|
var camera, scene, renderer;
|
|
|
|
+ var controls, group;
|
|
var objects = [];
|
|
var objects = [];
|
|
|
|
+ var enableSelection = false;
|
|
|
|
+
|
|
|
|
+ var mouse = new THREE.Vector2(), raycaster = new THREE.Raycaster();
|
|
|
|
|
|
init();
|
|
init();
|
|
- animate();
|
|
|
|
|
|
|
|
function init() {
|
|
function init() {
|
|
|
|
|
|
@@ -61,6 +63,9 @@
|
|
|
|
|
|
scene.add( light );
|
|
scene.add( light );
|
|
|
|
|
|
|
|
+ group = new THREE.Group();
|
|
|
|
+ scene.add( group );
|
|
|
|
+
|
|
var geometry = new THREE.BoxBufferGeometry( 40, 40, 40 );
|
|
var geometry = new THREE.BoxBufferGeometry( 40, 40, 40 );
|
|
|
|
|
|
for ( var i = 0; i < 200; i ++ ) {
|
|
for ( var i = 0; i < 200; i ++ ) {
|
|
@@ -97,46 +102,87 @@
|
|
|
|
|
|
container.appendChild( renderer.domElement );
|
|
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();
|
|
render();
|
|
- stats.update();
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|