React routing for Multi Scene project

Iā€™m a newb to REACT, I have a working set up following the multi scene tutorial, react method.

My question is, how/where does react call the initial state of the ā€œHome.tsxā€ or does it just initially create it at the end of ā€œreact-app.tsxā€ where is has "
const render = () => {
document.body.insertAdjacentHTML(ā€˜beforeendā€™, ā€˜

ā€™)
ReactDOM.render(


,
document.getElementById(ā€˜rootā€™)
)
}
"

Hello @Bill_Sullivan,

Using the following AFrame: React sample project as a reference, the base route / is coming from: A-Frame: React | 8th Wall | 8th Wall

<Route exact path={`${base}/`} component={Home} />

and right below that, itā€™s creating all of the other routes (one for each ā€œcolorā€ scene)

{Object.keys(COLORS).map(  // Create one route per color in COLORS.
  color => (<Route exact path={`${base}/${color}`} component={Scene} />)
)}

where COLORS is coming from lib/colors.ts:

const COLORS = {
  purple: '#7611B6',
  yellow: '#FFC828',
  red: '#DD0065',
  green: '#00EDAF',
  black: '#2D2E43',
  white: '#F9F9FA',
}

export {COLORS}

So basically you end up with the following ā€œscenesā€

  • /
  • /purple
  • /yellow
  • /red
  • /green
  • /black
  • /white

Hi Tony, Thanks for the response. I was a little confused (learning react) with the routing and was looking for where the page initial called the home.tsx page to load, but after some digging I saw that path={${base}/} component={Home} basically calls home.tsx when the rout page is loaded without any additional parameters. Still learning with REACH but making progress. Is there a way I can change from scene to scene without using the button page? Say from my own button on top like the login button? Or even from clicking on a 3D object in the page?

Sure, you can change scenes whenever you like.

Here is the code from the ā€œmenuā€ page that routes to the desired scene:

<Link to={path(location, color)} className={classes.nounderline}>

(where color is the destination)

and the back button: A-Frame: React | 8th Wall | 8th Wall

is calling onClick={() => history.push(path(location, '..'))}

Thanks Tony, As always you pull though! Just finished another one of your tutorials customizing the loading screens. Everything is falling into place. My only question would be Can I enlarge the loading image that pulses? Iā€™ve tried a couple tricks but nothing seems to make it any bigger, since itā€™s animated Iā€™m assuming the start and stop size of the pulse effect are in the pulse animation cssā€¦

1 Like

The source for the Loading Module is open source and the relevant pieces here can be found at:

Probably want to override this section with your own ā€œpulseā€ class (and !important)

Hope this helps!

Perfect, working, after watching so many of your demos saw this clip last night and thought this is tony managing the help desk at 8thwall https://youtube.com/shorts/xGEqYpIheBQ?si=wNjNzpP-b7-DyFKg

1 Like

Making progress, I have a custom button added to one of my scenes

click me

in my app.js I have it

**
AFRAME.registerComponent(ā€˜buttonā€™, {
init() {
const btn = document.getElementById(ā€˜myButtonā€™)
btn.addEventListener(ā€˜clickā€™, () => {
window.open(ā€˜https://google.comā€™, ā€˜_blankā€™)
})
}
})

I have the above code working but I donā€™t want to take visitors to google, I want to direct them to a different scene BUT how can I change the above code to call my react route below?

<Route exact path={${base}/kiosk_pyramid} component={PyramidScene} />

(my goal is to use the react routing but not the simple button page)

Happy to help :slight_smile:

instead of window.open you probably want to do something like history.push(path(location, kiosk_pyramid)) similar to what the back button does:

Donā€™t forget to import {path} from './routes' (make sure to use the relative path to this file)

Hi Tony,

I think what your suggesting above is React, the example of the back button is react so I canā€™t use that example to follow. I did write some javascript that could get the url, stripe the parameter and add what I wanted but this resutls in a page refresh and permission resuest.

Is there anyway from a javascript button that I can use the react routing or do I have to do all scene changes with react?

Is there anything I can add to this code to make it change sceen and not refresh page?
//custom back button in sphere upper right corner
AFRAME.registerComponent(ā€˜buttonā€™, {
init() {
const btn = document.getElementById(ā€˜myButtonā€™)
btn.addEventListener(ā€˜clickā€™, () => {
// window.open(ā€˜https://google.comā€™, ā€˜_blankā€™)
// history.push(path(location,ā€˜kiosk_pyramidā€™)) //this doenst work
})
}
})

Hi Tony, Sorry but itā€™s not working for me, here is what I have in app.js (I know the button works I can comment out google and it does it, I can alert path and I see the function, but nothing happens. My goal was to get this working first and then migrate the ability to change scenes via clicking on an object or say at end of an animation, then call to change scenes. Is the only way to change from Scene to scene via the react menu page?

import {path} from ā€˜./lib/routesā€™

AFRAME.registerComponent(ā€˜buttonā€™, {
init() {
const btn = document.getElementById(ā€˜myButtonā€™)
btn.addEventListener(ā€˜clickā€™, () => {
// window.open(ā€˜https://google.comā€™, ā€˜_blankā€™)
history.push(path(location, ā€˜kiosk_pyramidā€™))
})
}
})

Hi Tony,

For me itā€™s not working using the code you suggested.

For my project the goal is to click 3D objects on the screen and they direct you to different scenes.

If Iā€™m using the REACT multi scene switcher how can I change scene by tapping on an object on the screen when it calls tap-hotspot.js?

I need to be able to switch between scenes by clicking 3D objects in the scene and not using a UI menu like supplied in the react demoā€¦

  • wish I could get on a call with you, Iā€™m sure if I explained it better you would see what Iā€™m trying to do.

Hi @Bill_Sullivan , I had some time to play around with this today, and it does seem to be more complex than initially thought (changing react stuff from inside aframe) - if it was 2D UI as the trigger, probably a lot more simple. Iā€™m by no means a React expert, but with some help I was able to take the AFrame React sample project, clone it, and add some spheres to the scene. When you tap on a sphere, it takes you to the scene with that color cube

Check this out and I hope it gets to closer to what you are trying to implement!

the files I touched were:

  • lib/aframe-components.tsx
  • views/cube.html : to add spheres to the scene, and the ā€œchange-sceneā€ component to my a-scene
  • views/scene.tsx : created a ā€œchange-sceneā€ component and passed into AFrameScene and created a reactHistory variable that pulls from the react state.

Hope this helps!! And of other folks here have other suggestions or more elegant ways of doing this, please chime in! :slight_smile:

Tony, I just want to say thanks, I know you get tons of questions.

Iā€™m glade you had a chance to look into it and see yes itā€™s not that straight forward. I see in the demo you supplied that you add the objects in your material-ui-components.tsx below where the original UI menu of square 2D buttons were. I will see if I can get it working in a basic way for my scenario.

**Thank you again for trying, as Iā€™ve spent three days now banging my head against the wall.

I got so desperate I asked AI it said

in react I have a link that opens a page, how can I do the same thing with a javascript call " <Link to={path(location, ā€˜kiosk_pyramidā€™)} className={classes.nounderline}> Pyramid "

ChatGPT

ChatGPT

To achieve the same behavior with a JavaScript call instead of using the <Link> component from React Router, you can use the history.push() method. Hereā€™s how you can do it:

javascriptCopy code

import React from 'react';
import { useHistory } from 'react-router-dom';

const YourComponent = () => {
  const history = useHistory();

  const handleClick = () => {
    const path = '/kiosk_pyramid'; // Define the path you want to navigate to
    history.push(path);
  };

  return (
    <Button variant='contained' size='large' onClick={handleClick}>
      Pyramid
    </Button>
  );
};

export default YourComponent;

In this code:

  1. We import useHistory from ā€˜react-router-domā€™ to access the history object.
  2. Inside your component, we initialize history using the useHistory hook.
  3. We define a function handleClick which is called when the button is clicked. Inside this function, we use history.push() to navigate to the specified path, which is ā€˜/kiosk_pyramidā€™ in this case.
  4. The buttonā€™s onClick event is set to the handleClick function.
  5. Now, when the button is clicked, it will navigate to the ā€˜/kiosk_pyramidā€™ path programmatically.

Hi Bill,

I didnā€™t modify any of the 2D element menu stuff. I purely added 3 spheres to the scene, click event handlers to them as I thought that you wanted to change scenes by clicking on 3d models in your AR experience and not 2D UI elements. But if Iā€™m mis-understanding here, let me know.

Thanks!

Hi Tony,

The way you did it will have to work for me, Iā€™ve was hoping to have a javascript I could call to trigger the REACH router. The solution you provided does it thought React, so Iā€™ll follow what you did.

Above is what chat gpt provided, I would think there must be a way for javascript to call your React router but Iā€™m not fluent in React enough (or have time) to dive that deep into react.

**Could you show the code I provided above to your dev teamā€¦ maybe they can implement it somehow. Iā€™m sure more people would be happy to use javascript thought 90% of the project and use React just for routing. Having to learn React on top of everything else is not fun, specially when it really only accomplished the camera permissions and not really adds much else to the experience.

But thank you again and again for looking into this, I was beginning to loose hope. Now I have something I can go from.

Hiya Bill,

Give this a go, to see if it works for changing a URL via React Routing, when using Javascript.

    this.url = './page-to-load-via-react-routing'

    // simulate navigation to where you want to be (changes URL but doesn't navigate)
    window.history.pushState('', '', this.url)
    // simulate navigation again so that
    window.history.pushState('', '', this.url)
    // when you simulate back, the router tries to get BACK to "/url"
    window.history.go(-1)

Hey Mal,

Iā€™m neck deep in 3D development today but tonight Iā€™ll give it a try. I was able to create my own scene switcher with JavaScript but it was using reg change page which resulted in a page refresh / permission request. I see what you have and itā€™s making sense to me. Iā€™ll add another response once I have tested it. Thanks again Mal.

1 Like

It works on PC & android phone going to test it on iphone now.

One question. Do I need to call material-ui-components.tsx as my Home in the router, it does implement the back button but I can now do that with javascriptā€¦ Just trying to just use react for routing and reg 'ol javascript for everything else.

1 Like

Glad to hear it worked Bill! Iā€™ve tested that code on iOS, it should work across all devices.

If the material-ui-component based Back button is working, Iā€™d keep using it as it works through the React router - if it ainā€™t broke, donā€™t fix it etc!

You could try replacing a custom JS based back button it with the line below, and see what happens.

window.history.go(-1)

Mal