# Using FilesInput to handle drag and drop not working as expected

**URL:** https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061
**Category:** Questions
**Created:** [November 28, 2022, 4:43pm UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061 "2022-11-28T16:43:20Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![bdupree](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/bdupree/32/28367_2.png) [@bdupree](https://forum.babylonjs.com/u/bdupree)
#### Post date: [November 28, 2022, 4:43pm UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/1 "2022-11-28T16:43:20Z")

</div>

Hi everyone! I’m building a gLTF viewer similar to the Babylon Sandbox.

The user should be able to drag and drop files (gltf, bin, image assets) to the canvas and they should render. The problem is that the files seemingly load, but nothing happens in terms of adding them to the scene.

Here is a playground I extended to show what I mean.

> **[Babylon.js Playground](https://playground.babylonjs.com/#7PV3QQ%234)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

What I expect is for reload to be called and the dropped model to be present. What I get is the scene reloads and there is no model present.

Any advice? Thanks all.

---

<div class="post-metadata">

### Author: ![docEdub](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/docedub/32/14525_2.png) [@docEdub](https://forum.babylonjs.com/u/docEdub)
#### Post date: [November 28, 2022, 7:28pm UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/2 "2022-11-28T19:28:33Z")

</div>

Hi bdupree and welcome to the Babylon.js forum!

In your playground the callback given as the 3rd argument to `BABYLON.FilesInput` should use the 2nd argument for the `scene`. The 1st argument is a `File`.

See this fix: [https://playground.babylonjs.com/#7PV3QQ#8](https://playground.babylonjs.com/#7PV3QQ#8).

---

<div class="post-metadata">

### Author: ![bdupree](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/bdupree/32/28367_2.png) [@bdupree](https://forum.babylonjs.com/u/bdupree)
#### Post date: [November 29, 2022, 3:38am UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/3 "2022-11-29T03:38:55Z")

</div>

Ah! Thank you for catching that. Now this works on my local machine. However…

When I am importing the sources using `<script>`, everything works.

When I remove the `<script>`s and import via npm/ES6 modules I get the error “Please provide a valid .babylon file”. Any ideas here? Maybe I should create another question specifically for this?

---

<div class="post-metadata">

### Author: ![docEdub](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/docedub/32/14525_2.png) [@docEdub](https://forum.babylonjs.com/u/docEdub)
#### Post date: [November 29, 2022, 4:00am UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/4 "2022-11-29T04:00:55Z")

</div>

Try importing `@babylonjs/loaders` to get glTF support.

See [@babylonjs/loaders - npm (npmjs.com)](https://www.npmjs.com/package/@babylonjs/loaders).

---

<div class="post-metadata">

### Author: ![bdupree](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/bdupree/32/28367_2.png) [@bdupree](https://forum.babylonjs.com/u/bdupree)
#### Post date: [November 29, 2022, 4:17am UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/5 "2022-11-29T04:17:34Z")

</div>

Here are my imports

```auto
import { GLTFLoader } from '@babylonjs/loaders/glTF/2.0/glTFLoader'; 
import { GLTFFileLoader } from '@babylonjs/loaders/glTF/glTFFileLoader'
import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";
import '@babylonjs/loaders';
import '@babylonjs/core/Helpers/sceneHelpers';
import '@babylonjs/core/Loading/loadingScreen';

```

---

<div class="post-metadata">

### Author: ![docEdub](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/docedub/32/14525_2.png) [@docEdub](https://forum.babylonjs.com/u/docEdub)
#### Post date: [November 29, 2022, 4:23am UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/6 "2022-11-29T04:23:36Z")

</div>

Looks good. Can you post the rest of the module?

---

<div class="post-metadata">

### Author: ![bdupree](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/bdupree/32/28367_2.png) [@bdupree](https://forum.babylonjs.com/u/bdupree)
#### Post date: [November 29, 2022, 5:34am UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/7 "2022-11-29T05:34:44Z")

</div>

Sure thing. It happens in `onSceneReady`.

Just to reiterate – this code works when I import using

```auto
<script src="https://preview.babylonjs.com/babylon.max.js"></script>
<script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
<script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.js"></script>
<script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js"></script>

```

but not when using the following npm modules.

```auto
    "@babylonjs/core": "^5.34.0",
    "@babylonjs/loaders": "^5.34.0",
    "babylonjs": "^5.34.0",

```

```auto
import React, { Component } from "react";
import { withModule } from "react-hoc-di";
import BaseRenderer from "../renderer/Base3DRenderer";

import { EffectLayerSceneComponent } from '@babylonjs/core/Layers/effectLayerSceneComponent'; 
import { UniversalCamera } from '@babylonjs/core/Cameras/universalCamera'; // Must import this to enable gltf loading.
import { GLTFLoader } from '@babylonjs/loaders/glTF/2.0/glTFLoader'; // Must import this to enable gltf loading. // Must import this to enable gltf loading.
import { GLTFFileLoader } from '@babylonjs/loaders/glTF/glTFFileLoader'
import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";
import '@babylonjs/loaders';
import '@babylonjs/core/Helpers/sceneHelpers';
import '@babylonjs/core/Loading/loadingScreen';
// import { Ray } from '@babylonjs/core/Culling/ray';
import Base3DModule from "../module/Base3DModule";

class Base3DScene extends Component {

    constructor(props) {
        super(props);

        this.module = props.module;

        this.onSceneReady = this.onSceneReady.bind(this);
        this.onPointerDown = this.onPointerDown.bind(this);
        this.onPointerUp = this.onPointerUp.bind(this);

        this.renderSubject = this.module.renderSubject;
        this.sceneSubject = this.module.sceneSubject;
        this.renderRequestStream = this.module.renderRequestStream;
        this.scenePointerDownSubject = this.module.scenePointerDownSubject;
        this.scenePointerUpSubject = this.module.scenePointerUpSubject;
        this.sceneClickSubject = this.module.sceneClickSubject;
        
    }

    onPointerDown(evt, pickResult) {
        this.pointerDownTime = Date.now();
        this.renderRequestStream.on();
        this.scenePointerDownSubject.next(pickResult);
    }
    
    onPointerUp(evt, pickResult) {
        this.renderRequestStream.off();
        this.renderRequestStream.lease(2000);

        if (!this.pointerDownTime) {
            return;
        }

        this.scenePointerUpSubject.next([evt, pickResult]);

        if (this.camera) {
          // console.log(`CAMERA POSITION: ${this.camera.position}`)
          // console.log(`CAMERA RADIUS: ${this.camera.radius}`)
        }

        const offsetTimeMs = Date.now() - this.pointerDownTime;
        if (offsetTimeMs < 300) {
            this.sceneClickSubject.next([evt, pickResult]);
        }
    }

    componentDidMount() {
      BABYLON.GLTFFileLoader.IncrementalLoading = false;
      BABYLON.SceneLoader.OnPluginActivatedObservable.add((plugin) => {
          this._currentPluginName = plugin.name;
          if (this._currentPluginName === "gltf") {
              const loader = plugin
              // loader.transparencyAsCoverage = this.props.globalState.commerceMode;
              loader.validate = true;

              // loader.onExtensionLoadedObservable.add((extension: import("@babylonjs/loaders/glTF/index").IGLTFLoaderExtension) => {
              // this.props.globalState.glTFLoaderExtensions[extension.name] = extension;
              // });

              loader.onValidatedObservable.add((results) => {
                  if (results.issues.numErrors > 0) {
                      // this.props.globalState.showDebugLayer();
                  }
              });
          }
      });

    }
    

    onSceneReady(scene) {
      this.scene = scene;
      this.scene.onPointerDown = this.onPointerDown;
      this.scene.onPointerUp = this.onPointerUp;
  
      this.engine = scene.getEngine();
      this.engine.clearInternalTexturesCache();

      this.canvas = this.engine.getRenderingCanvas();
  
      if (this.props.noRenderLoop) {
        this.engine.setHardwareScalingLevel(100);
      } else if (window.innerWidth > 500) {
        this.engine.setHardwareScalingLevel(0.7);
      } else {
        this.engine.setHardwareScalingLevel(1);
      }
  
      scene.autoClear = Boolean(this.props.forceAutoClear);
  
      this.prepareCamera()
      // this.setupCamera();
      // this.setupLights();

      this.scene.createDefaultEnvironment({
        // createGround: false,
        createSkybox: false, 
      });

      // this.scene.clearColor = new Color4(236/255, 240/255, 241/255, 1);
      // this.scene.ambientColor = new Color4(236/255, 240/255, 241/255, 1);

      this.module.sceneSubject.next(this.scene);
      this.module.cameraSubject.next(this.camera);
      this.module.engineSubject.next(this.engine);

      const filesInput = new BABYLON.FilesInput(
        this.engine,
        this.scene,
        (sceneFile, scene) => {
          scene.createDefaultCamera(true);
          scene.createDefaultLight();
          console.log("Scene loaded")
        },
        progress => {
          console.log("Progress")
          console.log(progress)
        },
        null,
        remaining => {
          console.log("Texture loaded")
          console.log(remaining)
        },
        files => {
          BABYLON.Tools.ClearLogCache();
        },
        null,
        (_, _1, message) => {
          console.log("Error")
          console.log(message)
        });

        const canvas = document.getElementById("BaseRenderer");
        filesInput.monitorElementForDragNDrop(canvas);
    }

    prepareCamera() {
      // Attach camera to canvas inputs
      if (!this.scene.activeCamera) {
          this.scene.createDefaultCamera(true);

          const camera = this.scene.activeCamera;

          if (this._currentPluginName === "gltf") {
              // glTF assets use a +Z forward convention while the default camera faces +Z. Rotate the camera to look at the front of the asset.
              camera.alpha += Math.PI;
          }

          // Enable camera's behaviors
          camera.useFramingBehavior = true;

          const framingBehavior = camera.getBehaviorByName("Framing");
          framingBehavior.framingTime = 0;
          framingBehavior.elevationReturnTime = -1;

          if (this.scene.meshes.length) {
              camera.lowerRadiusLimit = null;

              const worldExtends = this.scene.getWorldExtends(function (mesh) {
                  return mesh.isVisible && mesh.isEnabled();
              });
              framingBehavior.zoomOnBoundingInfo(worldExtends.min, worldExtends.max);
          }

          if (this.props.autoRotate) {
              camera.useAutoRotationBehavior = true;
          }

          if (this.props.cameraPosition) {
              camera.setPosition(this.props.cameraPosition);
          }

          camera.pinchPrecision = 200 / camera.radius;
          camera.upperRadiusLimit = 5 * camera.radius;

          camera.wheelDeltaPercentage = 0.01;
          camera.pinchDeltaPercentage = 0.01;
      }

      this.scene.activeCamera.attachControl();
  }
    
    setupCamera() {
      this.camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, -Math.PI / 2, 50, Vector3.Zero(), this.scene);
      this.camera.useFramingBehavior = true;

      // this.camera.position = new Vector3(100, 70, 136);
      // this.camera.radius = Math.max(220, 130000 * (1 / window.innerWidth));
      // this.camera.lowerRadiusLimit = 130;
      // this.camera.upperRadiusLimit = 700;
      // this.camera.panningSensibility = 0; // Prevents Right-Click Drag to Translate.
      this.camera.attachControl(this.canvas, true);
    }
    
    setupLights() {
      // this.light = new BABYLON.DirectionalLight('light', new Vector3(0, -1, .6), this.scene);
      // this.light.intensity = 1.3;
    }

    onRender(scene) {
      if (!this.camera) {
        return;
      }
      const curZoom = this.camera.inertialRadiusOffset;
      if (curZoom !== this.lastZoom) {
        if (!this.renderRequestStream.isRendering()) {
          this.renderRequestStream.lease(500);
        }
        this.scenePointerDownSubject.next();
        this.lastZoom = curZoom;
      }

      this.renderSubject.next(scene);
    }

    render() {
      let engineOptions = {};

      const style = this.props.style || {width: "100%", height: "100%"}

      return (
          <BaseRenderer
              id="BaseRenderer"
              className={"none"}
              style={style}
              antialias
              adaptToDeviceRatio={true}
              onSceneReady={this.onSceneReady}
              engineOptions={engineOptions}
              onRender={this.onRender}
              noRenderLoop={this.props.noRenderLoop}
              resetSceneRequestSubject={this.resetSceneRequestSubject}
              />
      )
    }
}

export default withModule(Base3DScene);

```

---

<div class="post-metadata">

### Author: ![bdupree](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/bdupree/32/28367_2.png) [@bdupree](https://forum.babylonjs.com/u/bdupree)
#### Post date: [November 29, 2022, 6:06am UTC](https://forum.babylonjs.com/t/using-filesinput-to-handle-drag-and-drop-not-working-as-expected/36061/8 "2022-11-29T06:06:34Z")

</div>

Oh crap, I got it working. I noticed that I was importing Scene,Engine, FilesInput from `babylonjs` and other parts from `@babylonjs/core`.

I removed any imports from `babylonjs` and replaced all with `@babylonjs/core` imports and it worked.

Really appreciate your time helping me here @docEdub
