Forum

Switch Objects via javascript

17 December 2018 12:58
Hello,

i want to make a webapplication, where i can switch between four Objects. I made a blend4web example via nodes, but i want to make the same result with javascript and onclick events. The objects in this scene should be hidden, when only one is selected. I dont know, how to do that.
I hope someone have a solution for me.

my_switch_select(1).zip
Kind regards,

Bani
17 December 2018 21:50
The buttons in your project are not HTML element buttons, they are objects parented to the camera. To handle these "buttons" with javascript, you use B4W's pick_object(x,y) to test if a selectable object is under "x/y" when a click takes place. Clicks are detected by putting a handler on the entire canvas.

You can simply use the above code from the B4W manual and add some extra lines to switch your objects' visibility:

Put this into your .js file right under "place your code here":
var my_objects = ["Cylinder","Cone","Sphere","Cube"];
var my_buttons = ["type_1","type_2","type_3","type_4"];

var canvas_cont = m_cont.get_container();
canvas_cont.addEventListener("mousedown", function(event) {
  var obj = m_scenes.pick_object(event.offsetX, event.offsetY);
  if (obj)
    for (var i in my_objects) 
      if (m_scenes.get_object_name(obj) == my_buttons[i]) 
        m_scenes.show_object(m_scenes.get_object_by_name(my_objects[i]));
      else 
        m_scenes.hide_object(m_scenes.get_object_by_name(my_objects[i]));
});

In Blender, don't forget to:

- uncheck the checkbox Logic Editor under the Scenes tab, because otherwise the scene will still use your Logic Nodes!
- make the four "type" objects Selectable under their Object tabs.
- make the four switchable objects Dynamic Geometry… under their Object tabs.
- make the four switchable objects Hidden under their Object tabs. (I would personally leave the Cylinder visible to start with one object, but that's just me. )

…and then export the scene again!

Also, in the javascript file, don't forget that you need to add every module that comes up in the code at the top of the js file. In your case, go to the top where the modules are listed and add these two:

var m_cont = require("container");
var m_scenes = require("scenes");

Otherwise you will get a "m_something is not defined" error in the console. Whenever you get that error, you forgot to add the respective module in your code. It happens often…
18 December 2018 10:43
Hello Blend4Life,

thank you so much, for your reply.
That was very very helpfull and easy to read.

There is only one thing, that i wanted to make different. Yes i want to make my project work with the javascript, but I want to use html buttons instead of my selectable Objects in the scene.

Here is the file were my buttons are( i also implemented your code and it works fine, thx ) :

my_switch select.zip

(I made i project, where i could use html buttons, to controll Objects in my scene,
but only to resize or rotate an object. )
Kind regards,

Bani
18 December 2018 21:09
Well, the example I posted works ONLY with object buttons. With HTML buttons, the javascript is completely different (but even simpler). The new zip you attached is no good for several reasons, one of them your using a space in the project name. This is a bad idea, always use underscores.

Let's do HTML buttons starting from the original example you posted (my_switch_select(1).zip). Go back to that and here's what you do:

Put the following code into your .js file right under "place your code here":
var my_objects = ["Cylinder","Cone","Sphere","Cube"];

for (var i in my_objects) add_oc(i);

function add_oc(butt) {
  document.getElementById("my_button_"+butt).onclick=function() {
    for (var i in my_objects)
      if (i == butt) 
        m_scenes.show_object(m_scenes.get_object_by_name(my_objects[i]));
      else 
        m_scenes.hide_object(m_scenes.get_object_by_name(my_objects[i]));
  };
}
Also, in the javascript file, go to the top where the modules are listed and add:
var m_scenes = require("scenes");

In Blender…

- uncheck the checkbox Logic Editor under the Scenes tab, because otherwise the scene will still use your Logic Nodes!
- delete the four "type" objects and the four "empty" objects.
- make the four switchable objects Dynamic Geometry… under their Object tabs.
- make the four switchable objects Hidden under their Object tabs (again, you can leave one visible).

…and then export the scene again!

In the .html file, under the line that says <div id="main_canvas_container"></div>, add your buttons:
<button id="my_button_0" type="button" style="position:absolute;left:10px;top:10px">Cylinder</button> 
<button id="my_button_1" type="button" style="position:absolute;left:10px;top:40px">Cone</button> 
<button id="my_button_2" type="button" style="position:absolute;left:10px;top:70px">Sphere</button> 
<button id="my_button_3" type="button" style="position:absolute;left:10px;top:100px">Cube</button> 
I made very simple buttons - you can change the buttons to any design or complexity you want. You can also change to different tags, that is, you can use <button> to make buttons, or <img>, or <div> and so on… It does not matter. What matters is that each button must have its ID attribute, and the ID name must be the name you use in javascript, for example:

<img id="my_button_0">
<img id="my_button_1">


The reason why the numbering starts with ZERO is that in Javascript, the i loop iterates through the my_objects array, and arrays in Javascript start with zero, that is, if you define

var my_array = ["dog","cat","elephant"];

console.log(my_array[0]) will put dog in the console and [1] will print cat. It's really simple.

Our code is very elegant because you can add more buttons just by adding more elements to the array: ["Cylinder","Cone","Sphere","Cube","Torus","Monkey"]; … and for every element add a button in HTML: "my_button_4", "my_button_5" …
07 January 2019 16:49
Thank you soooooooooo much Blend4Life, that code is saving my Life!!!!!
I am so stunned!

I have one more question:
When I want to show and hide multiple Objects with several buttons like:
button_0 = "Cylinder" & "Cone"
button_1 = "Cone" & "Sphere"
button_2 = "Sphere" & "Torus"
button_3 = "Torus" & "Cylinder"
is that possible?
even with the array?
Kind regards,

Bani
07 January 2019 22:09
For that, I think it would be better to write a universal switching function that can switch ANY combination of on/off/toggle with the buttons directly programmable in HTML, so you have one solution for every possible case in the future.

Start from the previous example and, in the javascript file, delete everything you added under // place your code here.

Now, go to the HTML file and add the following code at the end of the HEAD section (above where it says </head>):
<script>

// universal button switching function for show, hide, toggle

function ubs() {
  var sc = b4w.require("scenes");
  for (var on_off_tog = 0; on_off_tog <= 2; on_off_tog++) {
    if (arguments[on_off_tog]) {
      if (!Array.isArray(arguments[on_off_tog])) arguments[on_off_tog] = [arguments[on_off_tog]];        
      for (var i in arguments[on_off_tog]) {
        var oref = sc.get_object_by_name(arguments[on_off_tog][i]);
        if (on_off_tog == 0 || on_off_tog == 2 && sc.is_hidden(oref)) 
          sc.show_object(oref);
        else
          if (on_off_tog == 1 || on_off_tog == 2 && sc.is_visible(oref))
            sc.hide_object(oref);
      }
    }
  }
}

</script>

Further below, delete your four button definitions and replace them with new ones:
<button type="button" onclick="ubs(null,null,'Cylinder')" style="position:absolute;left:10px;top:10px">toggle cylinder</button> 
<button type="button" onclick="ubs('Cube',['Sphere','Cylinder','Cone'],null)" style="position:absolute;left:10px;top:40px">show cube, hide rest</button> 
<button type="button" onclick="ubs(null,['Cylinder','Cone','Cube','Sphere'],null)" style="position:absolute;left:10px;top:70px">hide everything</button> 
<button type="button" onclick="ubs(['Cylinder','Cone'],['Sphere','Cube])" style="position:absolute;left:10px;top:100px">show cylinder+cone, hide rest</button>
As you can see, the buttons are now programmed directly in the button tags. The first parameter of ubs() passes the objects to show, the second parameter the objects to hide, and the third parameter the objects to toggle. You can pass a list in brackets [ ] or just a single string if you only have one object, or NULL if you have nothing to show/hide/toggle. The third parameter can be omitted completely (as seen in the last button), but for the first and second parameter, you must pass at least NULL.

Again, you don't have to use <button>, you can use the onclick functionality in other types, such as <image> and so on.
08 January 2019 10:38
Thank you very much!!! This helps me a lot.

If i want to make it looks nicer, can I implement the javascript code back to the .js file?
Kind regards,

Bani
08 January 2019 20:01
Nevermind, i did it myself. Very very cool!!!!. Thank you so much!
Kind regards,

Bani
 
Please register or log in to leave a reply.