Hi guys. I am struck at importing blob files with react (I am still new to react).
I want to import glob files to model. but ends up with the magic error and no camera is defined,
Here is some of my code
....///some codes before
this.state = {
blob: ""
};
this.onModelLoaded = this.onModelLoaded.bind(this);
}
onModelLoaded(e) {
let file = e.target.files[0];
var url = URL.createObjectURL(file);
console.log(file.name);
this.setState((state) => ({
...this.state,
blob: url
}));
return url;
I assign the blob value into the rootURL
within <Model/>
<Suspense fallback={null}>
<Model
rootUrl={this.state.blob}
sceneFilename=""
pluginExtension=".glb"
/>
</Suspense>
The entire code and the error can be seen in my codesandbox: babylonjs-react - CodeSandbox
@brianzinn is the daddy of this amazing framework
hi @Kayla_Man
The reason is that you cannot load a model with an empty string. GLB files specifically start with a special “magic” identifier. This will get your scene loading:
{this.state.blob !== "" &&
<Suspense fallback={null}>
<Model
rootUrl=""
sceneFilename={this.state.blob}
pluginExtension=".glb"
/>
</Suspense>
}
Your code would be a cleaner with a Functional Component. I can show you how to switch it over, if you want - it looks like you got that started from an Storybook on the main repo.
1 Like
Hi brian, I would like to see how to do it with a functional component if you dont mind to show!
Thank you,
K
This is one way:
babylonjs-react (forked) - CodeSandbox
import React, { Suspense, useRef, useState } from "react";
import "@babylonjs/loaders";
import { Engine, Scene, Model } from "react-babylonjs";
import { Vector3, Tools } from "@babylonjs/core";
export default () => {
const link = useRef();
const [model, setModel] = useState({ url: "", extension: "" });
function onFileInputChanged(e) {
if (e.target.files.length > 0) {
let file = e.target.files[0];
var url = URL.createObjectURL(file);
const extension = file.name.substring(file.name.lastIndexOf("."));
console.log(`loading '${extension}'.`);
setModel({ url, extension });
}
}
return (
<div onClick={() => link.current.click()}>
<h2>Upload files here!</h2>
<input
style={{ display: "none" }}
type="file"
ref={link}
onChange={onFileInputChanged}
/>
<Engine antialias adaptToDeviceRatio canvasId="babylonJS">
<Scene>
<arcRotateCamera
name="camera1"
alpha={Tools.ToRadians(0)}
beta={Tools.ToRadians(0)}
radius={4}
target={Vector3.Zero()}
minZ={0.001}
/>
<hemisphericLight
name="light1"
intensity={0.7}
direction={Vector3.Up()}
/>
{model.url !== "" && (
<Suspense fallback={<box name="fallback" />}>
<Model
rootUrl=""
sceneFilename={model.url}
pluginExtension={model.extension}
/>
</Suspense>
)}
</Scene>
</Engine>
</div>
);
};
edit: that’s a more or less direct translation. just added extension
otherwise state could be just a string.
1 Like
thank you!
i have another question but it isn’t related to the error or the component(they are all solved).
Is there any camera emb(similar to ArcRotateCamera
) or command which can create camera similar to scene.createdefaultcamera
in BabylonJS original library? I use but sometimes each object has different origin and it’s difficult to set the camera target.