Uibuilder + A-frame

Hello All,
I'm new in the forum and not so experienced with node red, im trying for the first time the uibuilder node and seems very powerful. Someone has already used it with a-frame for virtual/augmented reality? I would like to know how to pass the data from node red to uibuilder and show them dynamically into a-frame entity.
Thank you!

Hi @Danxsia, you are jumping in at the deep end - might I suggest you first get to grips with node red?

I recommend watching this playlist: Node-RED Essentials. The videos are done by the developers of node-red. They're nice & short and to the point. You will understand a whole lot more in about 1 hour. A small investment for a lot of gain.

As for uibuilder...
There is excellent and extensive documentation for uibuilder and a ton of threads on this forum with huge amounts of info and lots of examples in the flows library

Perhaps give it a go and when you get stuck, pop back with your questions?


What is an a-frame? Do you mean iframe?

Hello @Steve-Mcl!
Thank you for suggestions, of course I will come back with more clear question.

A-frame it's a web framework for virtual and augmented reality.

1 Like

Ah that's cool. Good luck figuring it all out.

That should work just fine with uibuilder.

First thing to learn is the separation between the front-end code (running in the browser) and the back-end (running on the server, Node-RED). uibulder acts as a bridge between the 2.

Create a new uibuilder node and strip all of the VueJS, bootstrap-vue code and libraries from it. Then add the A-Frame library and some basic HTML to your index.html file. Don't forget to keep the links to the uibuilderfe library and your index.js file.

Similarly strip out all of the Vue code from the index.js file. Check out the jquery example on the WIKI which may help you understand what to keep.

Basically, you need to initialise the uibuilderfe library once your web page is ready. uibuilder.start() does that. Then all you need is an uibuilder.onChange('msg', function(msg) { ... }) so that your code recognises when a new msg arrives from Node-RED.

If you want to send data back to node-red from your front-end code, you use the uibuilder.send() function.

That's it in a nutshell. Anything you send to the uibuilder node in Node-RED will appear in your onChange function and anything you send back to Node-RED appears on the top output port.

The second output port can be used to track client connections/disconnections so that you can deal with data caching and other similar tasks.

Not heard of anyone playing with A-Frame so no help there I'm afraid. However, I hope that you will consider contributing a WIKI article explaining how to do it once you've got it working so that others can benefit from your knowledge.

1 Like

Hi, I did create a prototype node using ARjs which uses Three.js which uses a-frame I believe. https://github.com/dceejay/node-red-arjs

It was meant for plotting virtual objects dynamically into a VR view on phone.

Never really released it as it was very picky (at the time) as to phone support and https connections to the server etc.. But it did work (for me)

This was just using regular Node-RED and a websocket i think. No ui-builder

Ah, the bad old days :smiley:

Hi @dceejay,
Sorry i'm not understand your link, maybe you wanted referring to this:

I've tried to install it manually, but I can't figure out how to use it because I can't see any new node in node-red editor.

It seems to look like what I want to do but without the need of three.js;
Using ar.js to recognize a marker and overlay on the marker the data coming from node-red.
I've followed Text (2D and 3D) from this examples:
and I was able to run it locally in uibuilder, but I missing the method to update text value with node-red data.

Sound like are most of the way there then...

at the end was easiest than expected :sweat_smile:

[{"id":"7324bec9.60682","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"80ef252e.9981e8","type":"uibuilder","z":"7324bec9.60682","name":"","topic":"","url":"artest","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":false,"showfolder":false,"x":290,"y":140,"wires":[[],[]]},{"id":"1b0fca24.78da76","type":"inject","z":"7324bec9.60682","name":"","props":[{"p":"payload"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":90,"y":140,"wires":[["6594bda9.8350a4"]]},{"id":"e623d882.4e3e38","type":"comment","z":"7324bec9.60682","name":"index.html","info":"<!doctype HTML>\n<html>\n<script src=\"https://aframe.io/releases/1.0.4/aframe.min.js\"></script>\n<script src=\"https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js\"></script>\n\n\n\n<body style=\"margin: 0px; overflow: hidden;\">\n\n<a-scene embedded vr-mode-ui=\"enabled: false;\" arjs=\"debugUIEnabled: false;\">\n\n\n\t<!-- 2D text -->\n\t<a-marker type=\"pattern\" url=\"data/hiro.patt\">\n\t\t\n\t\t<!-- positioning a plane directly below text for increased visibility; need to adjust position to avoid z-fighting.  -->\n\t\t<a-plane color=\"white\" rotation=\"-90 0 0\" position=\"0 -0.25 0\" width=\"3\" material=\"transparent: true; opacity: 0.90\"></a-plane>\n\n\t\t<!-- for more properties, see https://github.com/aframevr/aframe/blob/master/docs/components/text.md -->\n\t\t<a-text id=\"myText\" value= \"123\"  color=\"red\" rotation=\"-90 0 0\" align=\"center\" scale=\"2 2 2\"></a-text>\n\t\t\n\t\t<!-- positioning a second copy to attempt drop-shadow effect; need to adjust position to avoid z-fighting -->\n\t\t<!-- <a-text value=\"Hello, world!\" font=\"fonts/Exo2Bold.fnt\" color=\"black\" rotation=\"-90 0 0\" align=\"center\" scale=\"2 2 2\" position=\"0.01 -0.2 0\"></a-text> -->\n\n\t\t\n\t\t<!-- avoiding z-fighting is difficult; may want to render canvas to text instead -->\n\n\t</a-marker>\n\n    <a-entity camera></a-entity>\n    \n</a-scene>\n<script src=\"../uibuilder/vendor/socket.io/socket.io.js\"></script>\n<script src=\"./uibuilderfe.min.js\"></script>\n<script src=\"./index.js\"></script>\n\n\n</body>\n</html>\n\n","x":290,"y":100,"wires":[]},{"id":"34136a60.60bef6","type":"comment","z":"7324bec9.60682","name":"index.js","info":"'use strict';\n// vanilla JS\n\nuibuilder.start();\n\nuibuilder.onChange('msg', function (msg) {\n\tconsole.log(msg);\n\t//document.getElementById('myText').innerHTML = msg.payload;\n\tdocument.getElementById('myText').setAttribute('value', msg.payload);\n});\n","x":410,"y":100,"wires":[]},{"id":"6594bda9.8350a4","type":"function","z":"7324bec9.60682","name":"","func":"msg.payload =function getRandomInt(min = 1, max = 999) {\n\n\n  min = Math.ceil(min);\n\n\n  max = Math.floor(max);\n\n\n  return Math.floor(Math.random() * (max - min)) + min;\n\n\n}();\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":180,"y":220,"wires":[["80ef252e.9981e8"]]}]
1 Like