Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Three.js Cookbook

You're reading from   Three.js Cookbook Over 80 shortcuts, solutions, and recipes that allow you to create the most stunning visualizations and 3D scenes using the Three.js library

Arrow left icon
Product type Paperback
Published in Jan 2015
Publisher Packt
ISBN-13 9781783981182
Length 300 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Jos Dirksen Jos Dirksen
Author Profile Icon Jos Dirksen
Jos Dirksen
Arrow right icon
View More author details
Toc

Table of Contents (9) Chapters Close

Preface 1. Getting Started 2. Geometries and Meshes FREE CHAPTER 3. Working with the Camera 4. Materials and Textures 5. Lights and Custom Shaders 6. Point Clouds and Postprocessing 7. Animation and Physics Index

Dragging a file from the desktop to the scene

When you create visualizations, it is a nice feature to let your users provide their own resources. For instance, you might want to let the user specify their own textures or models. You can implement this with a traditional upload form, but with HTML5, you also have the option to let the user drag and drop a resource directly from the desktop. In this recipe, we'll explain how to provide this drag and drop functionality to your users.

Getting ready

The easiest way to prepare for this recipe is by first looking at the example we created for you. Open an example 01.14-drag-file-to-scene.html in your browser.

Note

Please note that this only works when running your own web server, or with security exceptions disabled.

Getting ready

When you drag and drop an image file onto the drop area (the dashed square), you'll immediately see that the texture of the rotating box is changed and the image that you provide is used.

In the following section, we'll explain how you can create this functionality.

How to do it...

To do this, please carry out the following steps:

  1. First, we have to set up the correct CSS and define the drop area. To create the dashed drop area, we add the following CSS to the style element in the head element of our page:
        #holder { border: 10px dashed #ccc; 
        width: 150px; height: 150px; 
        margin: 20px auto;}
        #holder.hover { border: 10px dashed #333; #333}

    As you can see in this CSS, we style the HTML element with ID holder to have a dashed border. The HTML for the holder div element is shown next:

      <body>
        <div id="holder"></div>
      </body>

    The drop area has been defined, so the next step is to add drag and drop the functionality to it.

  2. Then, we have to assign the correct event handlers so that we can respond to the various drag and drop related events.
  3. Just as in our previous recipes, we defined a function that contains all the required logic:
        function setupDragDrop() {
          var holder = document.getElementById('holder');
       
          holder.ondragover = function() {
            this.className = 'hover';
            return false;
          };
    
          holder.ondragend = function() {
            this.className = '';
            return false;
          };
    
          holder.ondrop = function(e) {
            ...
          }
        }

    In this code fragment, we defined three event handlers. The holder.ondragover event handler sets the class on the div element to 'hover'. This way, the user can see that they are allowed to drop the file there. The holder.ondragend event handler is called when the user moves away from the drop area. In the event handler, we remove the class of the div element. Finally, if the user drops a file in the designated area, the holder.ondrop function is called, which we use to process the dropped image.

  4. The final step is to process the dropped resource and update the material of our box. When a user drops a file, the following piece of code is executed:
          this.className = '';
          e.preventDefault();
    
          var file = e.dataTransfer.files[0],
          var reader = new FileReader();
          reader.onload = function(event) {
            holder.style.background = 
            'url(' + event.target.result + ') no-repeat center';
    
            var image = document.createElement('img');
            image.src = event.target.result;
            var texture = new THREE.Texture(image);
            texture.needsUpdate = true;
    
            scene.getObjectByName('cube').material.map = texture;
          };
          reader.readAsDataURL(file);
          return false;

    The first thing that happens is that we call e.preventDefault(). We need to do this to make sure that the browser doesn't just show the file, since that is its normal behavior. Next, we look at the event and retrieve the dropped file using e.dataTransfer.files[0]. We can't really do much with the file itself, since Three.js can't work directly with those, so we have to convert it to an img element. For this, we use a FileReader object. When the reader is done loading, we use the content to create this img element. This element is then used to create the THREE.Texture object, which we set as material for our box.

    How to do it...

How it works...

Drag and drop functionality isn't something that is supported by Three.js out of the box. As we saw in the previous section, we use the standard HTML5 drag and drop related events. A good overview of what events are available can be found in the official HTML5 documentation at http://www.w3.org/TR/html5/editing.html#drag-and-drop-processing-model.

One interesting thing to note is the addition of texture.needsUpdate = true to the ondrop event handler. The reason we need to set this property of the texture is to inform Three.js that our texture has changed. This is needed because WebGL and also Three.js caches textures for performance reasons. If we change a texture, we have to set this property to true to make sure that WebGL knows what to render.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image