Change Threejs layout for different screen sizes

This is a more general question and also my first topic in this forum:)

I am fairly new to Threejs and managed to build a working homepage, where some objects move vertically when the user scrolls up or down.
Now I want to adapt the layout to mobile devices and due to the smaller size, I want to let the objects scroll horizontally instead.
This would mean changing the position of all my elements and my raycasters.

My idea was to load a different Javascript-File for the different screen sizes and I found this code that someone came up with using enquire.js:

<script type="text/javascript">

// This loads JS files in the head element
    function loadJS(url)
    {
        // adding the script tag to the head
       var head = document.getElementsByTagName('head')[0];
       var script = document.createElement('script');
       script.type = 'text/javascript';
       script.src = url;

       // fire the loading
       head.appendChild(script);
    }

</script>

//Body
<script type="text/javascript">

    enquire.register("screen and (max-width: 599px)", {
        match : function() {
            // Load a mobile JS file
            loadJS('mobile.js');
        }
    }).listen();


    enquire.register("screen and (min-width: 600px) and (max-width: 899px)", {
        match : function() {
            // Load a tablet JS file
            loadJS('tablet.js');
            //console.log('tablet loaded');
        }
    }).listen();


    enquire.register("screen and (min-width: 900px)", {
        match : function() {
            // Load a desktop JS file
            loadJS('desktop.js');
            //console.log('desktop loaded');
        }
    }).listen();
</script>

I tried it but I got an error. Is this a possible solution, or what is the best way to change Threejs layouts for different screen sizes?

Hi @TacoCombo
you can try calling different functions instead of different files.
You can inspect window.innerWidth and choose your preferred function.
Remember to update the control after resize event, in your onWindowResize() callcack.

Thanks @alessandro_guarino for your reply!
So basically I say if window.innerWidth is smaller than a certain value, then generate these objects at that position, if not then give them a different position. Did I understand that correctly?

If that’s the case then I duplicate nearly all of my code and put it in different if statements?

Better not, I would say only the parts that change
like the positions, I seem to understand

Okay thanks a lot, I will try it out and let you know if it works:)

I’ve got to the point where a new cube appears when window.innerWidth is smaller than 568px.
The problem is, that it only appears when the window is loaded with this size, not when it’s resized to that size. Can i simply wrap the if-statement in a function and call that function in the resize-Event or how do I do that?

This is my code:

if (window.innerWidth < 568) {
  console.log("test");
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);
}

You need to manage both, into init settings and into resize callback.
Of course resize callback without adding object, you need to change position I remember.
It’s better to create objects outside ifelse stataement, inside only specs to change.

The thing is, that I also need to remove some objects. On desktop I have three rows ob objects that scroll when the user scrolls up or down. On mobile I want to have only one row of objects, so the other two shouldn’t be loaded on mobile.
This means that I need to create at least some of the objects in. an if-else statement

I did not know this spec
in any case good job
you can control the device just all init(), like this:

let isMobile = false;
if (
  /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(
    navigator.userAgent,
  )
  || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
    navigator.userAgent.substr(0, 4),
  )
) {
  isMobile = true;
}

and after use the vaiable isMobile (pay attention the code could be obsolete)

1 Like

I followed your tips and managed to achieve my desired effect, although I need to play around with the correct breakpoints for each view.
Thanks again for the big help @alessandro_guarino !!

1 Like

it’s a pleasure
good work

1 Like