Creating a dynamic canvas with a three-dimensional model using three.js: A step-by-step guide

I'm currently developing a website where I have integrated a canvas element to display a 3D object (specifically, a cube) using three.js. The canvas is housed within a div, following the guidelines found in various documentation.
The issue arises when the screen size is adjusted - as it becomes smaller, the canvas and object scale down accordingly, which functions as intended. However, upon resizing the screen to a larger size, the canvas extends and takes up the entire page.
I am seeking a solution to maintain consistent dimensions for both width and height of the canvas regardless of the screen size.
Thank you in advance.

<!DOCTYPE html>
<html>
<head>
<meta charset= UFT-8>
<title>tema</title>
<style type="text/css">

div{
width: 50%;
margin-left: 20px;
margin-right: 100px;
margin-top: 20px;
margin-bottom: 20px;
border: 2px solid blue;
}
</style>
</head>
<body>
<section class="menu">
<div id="container"></div>

<script src="https://ajax.googleapis.com/ajax/libs/threejs/r76/three.min.js" ></script>

<script type="text/javascript">
function init(){

width = 500;
height = 500;

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera( 75, width/height, 0.1, 1000 );

camera.position.z = 500;

renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height);
renderer.setClearColor( 0xffffff);
renderer.setPixelRatio( window.devicePixelRatio );


contenedor = document.getElementById('container');

contenedor.appendChild(renderer.domElement);



var obj = new THREE.CubeGeometry(100,100,100);
var material = new THREE.MeshNormalMaterial();


body = new THREE.Mesh(obj,material);


scene.add( body );



window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {

camera.aspect = window.innerWidth/ window.innerHeight;

camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );

}


var animate = function () {

requestAnimationFrame( animate );


body.rotation.x+=0.01;
body.rotation.y+=0.01;



renderer.render(scene, camera);
};
init();
animate();

</script>
</section>
</body>
</html>

Answer №1

It's quite common to overlook this detail - resizing the renderer based on the window's dimensions instead of the container div can lead to unexpected results. It's important to consider the specific container div width and height for more accurate rendering.

You can try updating the onWindowResize function with the following code snippet:

function onWindowResize() {

    camera.aspect = container.clientWidth / container.clientHeight;

    camera.updateProjectionMatrix();

    renderer.setSize(container.clientWidth, container.clientHeight);
}

Answer №2

By utilizing javascript media queries, you have the option to adjust the position of an object or the camera instead of altering the canvas size. Take a look at the code snippet below which proved useful in my own scenario.

loader.load('assets/check.glb', handle_load);
var mesh;
    function handle_load(gltf) {

        console.log(gltf);
        mesh = gltf.scene;
        console.log(mesh.children[0]);
        mesh.children[0].material = new THREE.MeshLambertMaterial();
scene.add( mesh );
        mesh.position.z = 3;
        mesh.position.x = 1.8;
        mesh.position.y = -0.4;
        mesh.rotation.x = 0.3;
function media(x) {
  if (x.matches) { 
        mesh.position.z = 1;
        mesh.position.x = 0;
        mesh.position.y =-0.4;
       
  } else {
        mesh.position.z = 3;
        mesh.position.x = 1.8;
        mesh.position.y = -0.4;
    
  }
}

var x = window.matchMedia("(max-width: 700px)")
media(x) 
x.addListener(media);
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implementing Facebook Javascript SDK to enable login and trigger re-authentication using React Web and Typescript within a component

As a newcomer to stack overflow, I welcome any suggestions on how I can improve my question. I'm in need of guidance concerning logging a user into facebook and requiring them to authenticate their profile or select another profile manually, rather t ...

What is the best way to enable the noWrap feature for a Typography component that is within an Alert or AlertTitle component?

My goal is to have a Typography component truncate overflowing text with an ellipsis. However, I am facing an issue where this doesn't work when the Typography component is nested inside an Alert component. Below is a snippet of the code in question: ...

Discover the steps to click a button in React that is initially hidden until viewed through inspection by pressing Ctrl + Shift + I

I have encountered an issue with a button that I need to click, but I am unable to do so unless I inspect it first. Here is the Xpath for reference: //*[@id="react-root"]/section/main/div/header/section/div[1]/div[1]/span/span[1]/button The full Xpath i ...

Looking for a node.js IDE on OS X that can display JSON objects similar to how they appear in the console of Chrome or Firefox?

While using Google Chrome, I noticed that when I console.log(object), a detailed view of the object is displayed in the console instead of just a string representation. This feature is incredibly useful. Unfortunately, when running node.js scripts on my ...

Saving Backbone.js Collection as Text File on HDD & Re-importing Data

After experimenting with Backbone.js for a while, I've relied on localStorage to store most of my app data. However, I now want to explore the possibility of exporting my collection to plain text for easy backup purposes. Essentially, I envision a fea ...

I'm having trouble getting my modal to open, it just displays the information on my page instead

I am encountering some difficulties with my model window. I would like it to open a modal that shows a larger version of the photo and description when the thumbnail is clicked. However, I have not been able to get it to work properly. The only time it pop ...

Reduce XSLTProcessor output by 50%

I have a persistent problem (from my perspective, at least). Every time I use XSLTProcessor.transformToFragment, the output is consistently halved compared to the input. For example, when I receive 200 entries in an XML file as a response from a webservi ...

Organize various base arrangements within Angular version 2

One thing I can accomplish in my angularjs application using ui.router is: $stateProvider .state('app', { url: '', abstract: true, template: '<div data-ui-view></div>' ...

Designing a multi-platform web browser application for Android, iOS, and Windows 10

I've developed several web applications using HTML5 technology and now I'm interested in creating my own custom web browser specifically tailored for my apps/sites. I want it to have a native appearance, but essentially just wrap around my web ap ...

Adjust the span's width to make it shift position

Currently, I am in the process of learning HTML and there is a specific question that has come up for me. Within my <div class="input-group">, there are three elements: one span, one input field, and another span: <span class="input-group-addon q ...

Initiating a SOAP request to utilize your custom services

Currently, I am in the process of creating a web application that includes providing various web services. After completing the domain model, we are now focusing on implementing both the User Interface (UI) and controller. The controller will consist of t ...

What are the steps to integrate Material-UI Tabs with react-router?

I've been working on integrating Material-UI tabs with routing in my project. Although the routing is functioning well and displaying the selected tab, the smooth animation while navigating between tabs seems to be broken. How can I ensure that react ...

Tips for automatically focusing a div upon page load

Here is a code snippet for you to review: <div id="details"> <nav> <a href="#1"><span>Summary</span></a> <a href="#2"><span>Perso ...

Transform JSON data into a CSV file using JavaScript or C# in an MVC4 framework, then import the data into

I am facing an issue with my website. Currently, when a user submits an application form, an email is sent. However, I would like to create a CSV file containing the form data and then automatically populate my database using this CSV file. Here is my ASP ...

Bootstrap dropdown menu fails to adapt to updated navbar height

I recently made a modification to the navbar size on my website, increasing it from 50px to 63px by tweaking a line in the bootstrap.css file. The exact code snippet I utilized for this adjustment is as follows: .navbar { position: relative; min ...

Go to a different page section using MUI 5

I am currently working on a React application and I want to implement a functionality where pressing a button on my Nav Bar will navigate to a specific section on the first page. To achieve this, I have created an onClick function for my button: const onNa ...

The module 'PublicModule' was declared unexpectedly within the 'AppModule' in the Angular 4 component structure

My goal is to create a simple structure: app --_layout --public-footer ----public-footer.html/ts/css files --public-header ----public-header.html/ts/css files --public-layout ----public-layout.html/ts/css files In public-layout.html, the stru ...

Retrieving the inner content of several paragraph elements, all consolidated into a single string

I'm trying to extract the inner HTML of multiple paragraph elements from a string and I need some help. Here's an example input: let HTML = "<p class="Paragraph" >Hello, World 1!</p><p class="Paragraph" >Hell ...

The FaceBook modal is failing to appear

Attempting to implement FaceBook Login through a modal. Upon clicking the button below, the FaceBook Login Modal should appear. <li> <a href="#sign-in-dialog" class="login sign-btn" title="Sign In">Sign In</a> </li> The HTML co ...

Issue with ReactJS: onChange event does not function properly when value is changed using jQuery

This is the reactjs code I am working with: <input name="date" id="date" value={this.state.listManage.date} onChange={this.handleForm} type="text" /> When I manually type in the input field, the onChange function works ...