Babylonjs and React in Javascript

Greetings,

I recently started using Babylonjs and wanted to combine it with React.
I found this setup for it: How to use Babylon.js with ReactJS - Babylon.js Documentation

My problem is, that I don’t want to use TypeScript and “This is a TypeScript example, so for JavaScript just remove the data types.” isn’t very helpful for a beginner like me…

Does someone have the JavaScrip version and could write it to me? (+add it to the tutorial in case someone runs into the same problem as me)

Would really appreciate any help.

Thats how I tried to make it work btw:

import * as BABYLON from ‘babylonjs’;

export {
engine,
scene,
canvas
};

export {
engineOptions,
adaptToDeviceRatio,
onSceneMount,
width,
height
};

export default {

scene: BABYLON.Scene,
engine: BABYLON.Engine,
canvas: HTMLCanvasElement,


onResizeWindow() {
    if (this.engine) {
        this.engine.resize();
    }
},

componentDidMount() {
    this.engine = new BABYLON.Engine(
        this.canvas,
        true,
        this.props.engineOptions,
        this.props.adaptToDeviceRatio
    );

    let scene = new BABYLON.Scene(this.engine);
    this.scene = scene;

    if (typeof this.props.onSceneMount === 'function') {
        this.props.onSceneMount({
            scene,
            engine: this.engine,
            canvas: this.canvas
        });
    } else {
        console.error('onSceneMount function not available');
    }

    // Resize the babylon engine when the window is resized
    window.addEventListener('resize', this.onResizeWindow);
},

componentWillUnmount() {
    window.removeEventListener('resize', this.onResizeWindow);
},

onCanvasLoaded(c) {
    if (c !== null) {
        this.canvas = c;
    }
},

render() {
    // 'rest' can contain additional properties that you can flow through to canvas:
    // (id, className, etc.)
    let { width, height, rest } = this.props;

    let opts;

    if (width !== undefined && height !== undefined) {
        opts.width = width;
        opts.height = height;
    }

    return (
        <canvas
            {...opts}
            ref={this.onCanvasLoaded}
        />
    );
}

}

And:

import * as React from ‘react’;
import * as BABYLON from ‘babylonjs’;
import BabylonScene from ‘./babylon.js’; // import the component above linking to file we just created.

class PageWithScene extends React.Component{
onSceneMount(e) {
const { canvas, scene, engine } = e;

    // This creates and positions a free camera (non-mesh)
    let camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);

    // This targets the camera to scene origin
    camera.setTarget(BABYLON.Vector3.Zero());

    // This attaches the camera to the canvas
    camera.attachControl(canvas, true);

    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    let light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

    // Default intensity is 1. Let's dim the light a small amount
    light.intensity = 0.7;

    // Our built-in 'sphere' shape. Params: name, subdivs, size, scene
    let sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);

    // Move the sphere upward 1/2 its height
    sphere.position.y = 1;

    // Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene
    let ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene);

    engine.runRenderLoop(() => {
        if (scene) {
            scene.render();
        }
    });
}

render() {               
    return (
        <div>
            <BabylonScene onSceneMount={this.onSceneMount} />
        </div>
    );
}

}

Hi @Kai_Jessen and welcome to the forum!:slightly_smiling_face:

DataTypes in TypeScript are declared like this:
var myText: string = "bla";

While JavaScipt ist just:

var myText = "bla";

You may take a look at the PlayGround on the TypeScript website -> TypeScript playground in which you can convert Ts into Js.

Hello @wulf11,

My compiler (Visual Studio Code) still complains about unreachable code and unexpected tokens, but I can perhaps use some of the converted code to help me out.
I will try to build on that.

Not a solution (would have been too nice to be resolved in one go, wouldn’t it?), but still thank you for the fast answer ^^

@Kai_Jessen sorry for the “short” answere, can’t provide any code now because I just have lunch break at work :sweat_smile:

just another short hint: did you checkout the github example? I think it’s compiled in Js

@wulf11 Oh, thx again!

Sry to have bothered you -.-
A senior of mine just helped me and this code is working for me (there may still be things missing, but it works):

import React from ‘react’;
import PropTypes from ‘prop-types’;
import * as BABYLON from ‘babylonjs’;

class Scene extends React.Component {

componentDidMount() {
    this.engine = new BABYLON.Engine(
        this.canvas,
        true,
        this.props.engineOptions,
        this.props.adaptToDeviceRatio
    );

    let scene = new BABYLON.Scene(this.engine);
    this.scene = scene;

    if (typeof this.props.onSceneMount === 'function') {
        this.props.onSceneMount({
            scene,
            engine: this.engine,
            canvas: this.canvas
        });
    } else {
        console.error('onSceneMount function not available');
    }

    // Resize the babylon engine when the window is resized
    window.addEventListener('resize', this.onResizeWindow.bind(this));
}

componentWillUnmount() {
    window.removeEventListener('resize', this.onResizeWindow.bind(this));
}

onResizeWindow() {
    if (this.engine) {
        this.engine.resize();
    }
}

onCanvasLoaded(c) {
    if (c !== null) {
        this.canvas = c;
    }
}

render() {
    // 'rest' can contain additional properties that you can flow through to canvas:
    // (id, className, etc.)
    let { width, height } = this.props;

    let opts = {};

    if (width !== undefined && height !== undefined) {
        opts.width = width;
        opts.height = height;
    }

    return (
        <canvas
            {...opts}
            ref={this.onCanvasLoaded.bind(this)} />
    );
}

}

Scene.propTypes = {
width: PropTypes.number,
height: PropTypes.number,
onSceneMount: PropTypes.func,
engineOptions: PropTypes.object,
adaptToDeviceRatio: PropTypes.bool
};

export default Scene;

import React from ‘react’;
import PropTypes from ‘prop-types’;
import * as BABYLON from ‘babylonjs’;

class Scene extends React.Component {

componentDidMount() {
    this.engine = new BABYLON.Engine(
        this.canvas,
        true,
        this.props.engineOptions,
        this.props.adaptToDeviceRatio
    );

    let scene = new BABYLON.Scene(this.engine);
    this.scene = scene;

    if (typeof this.props.onSceneMount === 'function') {
        this.props.onSceneMount({
            scene,
            engine: this.engine,
            canvas: this.canvas
        });
    } else {
        console.error('onSceneMount function not available');
    }

    // Resize the babylon engine when the window is resized
    window.addEventListener('resize', this.onResizeWindow.bind(this));
}

componentWillUnmount() {
    window.removeEventListener('resize', this.onResizeWindow.bind(this));
}

onResizeWindow() {
    if (this.engine) {
        this.engine.resize();
    }
}

onCanvasLoaded(c) {
    if (c !== null) {
        this.canvas = c;
    }
}

render() {
    // 'rest' can contain additional properties that you can flow through to canvas:
    // (id, className, etc.)
    let { width, height } = this.props;

    let opts = {};

    if (width !== undefined && height !== undefined) {
        opts.width = width;
        opts.height = height;
    }

    return (
        <canvas
            {...opts}
            ref={this.onCanvasLoaded.bind(this)} />
    );
}

}

Scene.propTypes = {
width: PropTypes.number,
height: PropTypes.number,
onSceneMount: PropTypes.func,
engineOptions: PropTypes.object,
adaptToDeviceRatio: PropTypes.bool
};

export default Scene;

2 Likes

It would really help if this code was put into the using react with Babylon page!