FORUM CTRLX AUTOMATION
ctrlX World Partner Apps for ctrlX AUTOMATION
05-01-2023 04:32 PM
Hello All,
I have made a local script containing a simulation in Threejs.
This works pretty good when only using the local script. However, now I want to show this local script inside a window inside my 'main' HMI. The issue I have is that I cannot correctly show the ThreeJS visualisation inside this window.
When I switch to this screen, the visualisation appears underneath the screen, not inside the container.
And when I switch screens, the visualisation remains to be visiable under the screen. But it should be closed.
I am not too familiar with javascript. Is there anything I am doing wrong?
Solved! Go to Solution.
05-02-2023 07:52 AM
WebIQ does not have any "Window" widget - are you talking about a dialog?
In any case this looks more like a general JavaScript question or ThreeJS question than a WebIQ question to me.
With the limited given information: you are probably rendering ThreeJS inside the wrong HTML element.
05-02-2023 09:53 AM
Hello,
You are right. What I meant to say is that I created a screen. The screen contains a container. And inside this container I call the local script.
I agree that this is a more general question. I am fairly new with programming in Javascript so sometimes it's a little hard to differentiate webiq and javascript. I based the script on this WebIQ - Render a 3D model (boschrexroth.com) tutorial.
I will look for more information on this subject online,
Thank you anyway.
05-02-2023 03:03 PM
Hello,
I did some furter investigating. And you are absolutely right.
The threejs script is rendered in a seperate HTML element like this:
I tried doing it like this: body = document.getElementsByName("threejs_script") but this does not work.
When I log the shmi.ctrl(".threejs_script") it appears that the object does exist.
I am aware that this has noting to do with webiq. But I am a bit lost.
Is there a way to render the threejs script inside the container I created via webiq?
Thank you so much!
05-02-2023 03:58 PM
1. document.getElementsByName("threejs_script") is looking for an HTML element that has an attribute with the name "threejs_script" - please see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByName
2. shmi.ctrl(".threejs_script") - we are working with modern web technology here which is asynchronous so the script might not have been loaded. In any case this would not help as you have to change where the script renders the element - changing the position of the LocalScript will not make any difference here.
3. "Is there a way to render the threejs script inside the container I created via webiq?" - it all comes down to an HTML element where you have to insert the ThreeJS element. As WebIQ is completely web-based a container is simply a <div> HTML tag.
I can't help you any further as it is impossible to know what your code does without seeing the code utilizing ThreeJS
05-02-2023 04:04 PM
05-02-2023 04:36 PM
Nevermind, I have solved it with your hint "simply a <div> HTML tag".
I was thinking too complicated. I insterted a HTML widget with a new DIV. And inside the script I use this DIV.
Easy as that.
Thank you for your help and time. Much appreciated.
05-02-2023 04:36 PM
The code does exactly what you're telling it to do: append the ThreeJS object to the end of the HTML document. I highly recommend getting to know JavaScript better - there are lots of free resources available, otherwise you'll run into such issues over and over again probably.
Remove this code:
let container = document.createElement( 'div' );
body.appendChild( container );
Wrap all of your code inside the module.run method (excluding the self.onDisable code) inside this code:
shmi.onReady(
{
controls: {
cont: ".YOUR_CONTAINER_NAME"
}
}, function (resolved) {
const myContainer = resolved.controls.cont,
container = myContainer.element;
// Put all your code in here (except onDisable)!
// ...
// ....
}
);
Name your container where you want to add it YOUR_CONTAINER_NAME.
Your code also causes memory leaks as you're always creating a new listener when the LocalScript is executed and storing it in the variable tok, but never unsubscribe. Rename tok to subscriptionToken to fix this issue (see onDisable!)
As I wrote before everything is executed asynchronously so we have to wait until our container widget has been initialized! Only then ThreeJS can actually find the HTML element we want to use.
I haven't tested the code above, but it should work.
05-02-2023 04:39 PM - edited 05-02-2023 04:40 PM
This code can wreak havoc - you now have created invalid HTML code - you cannot have two <body> elements in your HTML code! However, browsers are extremely tolerant, unfortunately. Whatever happens here is undefined. However, removing the <body></body> should work.
https://www.w3schools.com/tags/tag_body.asp
Also, this might work or might not work all depending on timings - this means that it might work on your (fast) system, but it might not work on other systems or only intermittently.
Therefore you should always use shmi.onReady to wait for widgets!