Adjust the size of the scene to make it smaller and position the canvas within a div

My current project involves Three.js and can be accessed here in its entirety.

The particles in the project have a lot of vertical space around them that is unoccupied. I am trying to find a way to reduce this space or put the project inside a div. I tried adjusting renderer.setSize but it distorted the scene. Placing it in a div didn't yield any results for me either.

My formal training in web design was limited, only covering the basics. I had to learn things like this online, so I apologize if my questions seem simplistic.

var SEPARATION = 70, AMOUNTX = 25, AMOUNTY = 20;

var container, camera, scene, renderer;

var particles, particle, count = 0;

var mouseX = 0, mouseY = 0;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

...

Answer №1

To ensure a consistent height for your canvas, you can establish a fixed height and incorporate it into both the onWindowResize function and the init function.

Here is an example:

// set a fixed canvas height 
var fixedCanvasHeight = 200;

function init(){
    // adjust the separation for a more even particle distribution 
    SEPARATION = window.innerWidth/AMOUNTX;
    ...
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / fixedCanvasHeight, 1, 10000 );
    ...
    renderer.setSize( window.innerWidth, fixedCanvasHeight );
    ...
}

function onWindowResize() {        
    // adjust the separation for a more even particle distribution 
    SEPARATION = window.innerWidth/AMOUNTX;

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera.aspect = window.innerWidth / fixedCanvasHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, fixedCanvasHeight );
}

Answer №2

Here is a combined solution based on suggestions from cameraman and WestLangley:

  • Globalized variables WIDTH and HEIGHT are used
  • HEIGHT is set to a fixed value
  • camera.fov is adjusted for zooming

var SEPARATION = 70,
  AMOUNTX = 25,
  AMOUNTY = 20,
  // Globalized width & height varialbes
  WIDTH = window.innerWidth, // width still references the window width
  HEIGHT = 200; // height is now a fixed value (if this needs to be dynamic, you'll need to calculate it)

var container, camera, scene, renderer, particles, particle, count = 0;

var mouseX = 0,
  mouseY = 0;

var windowHalfX = WIDTH / 2;
var windowHalfY = HEIGHT / 2;

// Remaining code omitted for brevity
<script src="http://threejs.org/build/three.js"></script>
<script src="http://threejs.org/examples/js/renderers/CanvasRenderer.js"></script>
<script src="http://threejs.org/examples/js/renderers/Projector.js"></script>

Answer №3

It seems like you're struggling with placing the canvas inside a div. Using a div allows for better positioning and sizing of the canvas.

Check out the essential code snippets from your updated example: http://codepen.io/anon/pen/ybBVYX

var SCREEN_WIDTH, SCREEN_HEIGHT;

// initialization
container = $('.webgl');
SCREEN_WIDTH = container.width();
SCREEN_HEIGHT = container.height();

camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.z = 1000;

renderer = new THREE.CanvasRenderer({alpha:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
container.append( renderer.domElement );

// resizing
function onWindowResize() {

  SCREEN_WIDTH = container.width();
  SCREEN_HEIGHT = container.height();
  
  camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
  camera.updateProjectionMatrix();

  renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

}
html, body {
  color: #ff0000;
  height: 100%;
}
.header {
  height: 60%;
  background-color: #ccc;
}
.webgl {
  height: 40%;
}
<div class="header">
  <p class="test">Hello</p>
  <a href="">Link</a>
</div>

<div class="webgl"></div>

If you want to maintain the aspect ratio, you'll need to set the width or height of both your div and the canvas element explicitly, for example, using jQuery:

SCREEN_WIDTH = container.width();
SCREEN_HEIGHT = SCREEN_WIDTH * aspectRatio;

container.height( SCREEN_HEIGHT );

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

React: Updating useState array by removing the first element triggered by an event or timer

I am currently working on a function that populates a useState array containing objects representing cars. These cars appear on the left side of the screen and move across until they are off-screen. My goal is to remove these cars from the state array once ...

The client side script "/socket.io/socket.io.js" was not located, therefore the Express-generator project was used instead

I have been working on integrating the "chat-example" from Socket.IO's official website into an Express-generator generated project while keeping the structure of the project intact. I have made minimal changes to the code to fit it into the existing ...

Can a substring within a string be customized by changing its color or converting it into a different HTML tag when it is defined as a string property?

Let's discuss a scenario where we have a React component that takes a string as a prop: interface MyProps { myInput: string; } export function MyComponent({ myInput }: MyProps) { ... return ( <div> {myInput} </div> ...

Karma and RequireJS fetching files beyond the base URL

My goal is to set up automatic testing using karma with the following file structure: /assests /css /font /img /js /collection /lib /model /plugin /spec /view test-main.js main.js /templates index.html karma.conf.js In my ...

Traversing an array of objects to extract and display the key-value pairs for each object

Here is an array I am working with: const cuisines = [ { african: "African" }, { american: "American" }, { arabian: "Arabian" }, { argentine: "Argentine" }, { asian: "Asian" }, { asian_fusion: "Asian Fusion" }, { australian: "Australi ...

The node application route appears to be malfunctioning

Recently delving into the world of node JS, I encountered an issue while working on my application with the following 3 files. http.createServer(app).listen(**app.get('port')**, function(){ The error message reads 'undefined is not a func ...

When you press the submit button, the screen automatically scrolls down but no action is taken

I'm currently utilizing Selenium WebDriver (Java) with the Firefox driver. Upon trying to click the 'Submit' button on a particular page, it only results in scrolling down the screen slightly. The button itself does not register the click, c ...

Elements are randomly glitching out with CSS transitions in Firefox

Chrome is working perfectly for me, but when I switch to Firefox it behaves differently than expected I am attempting to create a simple animation (utilizing transitions) that continuously runs on mouseover and smoothly returns to the starting position on ...

Implementing Next.js in a live production environment

I've been using next.js for some time now, but I'm still trying to wrap my head around how it operates in a production environment. As far as I understand it, when a request is made to the server, the server retrieves the requested page from the ...

Populate the dropdown menu with data from a JSON file

Recently, I created a custom JSON file and wanted to populate a select>option using this data. However, I encountered an error message saying: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///C:/.../p ...

How can I utilize the mapping function on a promise received from fetch and display it on the page using React

As I'm using fetch to return a promise, everything is working fine. However, I am facing an issue while trying to map over the fetched data. When I check my console log, it shows "undefined." const dataPromise = fetch('http://api.tvmaze.com/sche ...

Displaying the Selected Value from the DropDown in the Menu

I am working with Bootstrap5 and have the following dropdown menu in my code. Instead of displaying "Year," I would like to show which member was selected. How can I achieve this? <div class="dropdown"> <button class="btn btn- ...

Steps for sorting items from a list within the past 12 hours

I'm currently working with Angular and I have data in JSON format. My goal is to filter out items from the last 12 hours based on the "LastSeen" field of the data starting from the current date and time. This is a snippet of my data: { "Prod ...

When utilizing AJAX within a for loop, the array position may not return the correct values, even though the closure effectively binds the scope of the current value position

Is this question a duplicate of [AJAX call in for loop won't return values to correct array positions? I am following the solution by Plynx. The issue I'm facing is that the closure fails to iterate through all elements in the loop, although the ...

Notification pop-up for accepting cookies on a website

I am curious about how to insert a .js code into a button within a bootstrap alert so that when the user clicks 'accept', the alert box does not reappear. Thank you very much. Here is the code I have, but it is not working. Javascript: $(".bt ...

Using jQuery to change date format from mm/dd/yy to yyyy-dd-mm

I need to transform a date in mm/dd/yy format from an ajax response into yyyy-mm-dd format using jquery. Is there a built-in function in jquery that can handle this conversion for me? ...

How can I address the issue of an inner content scroll bar?

I am facing an issue with the scroll bar on inner content. When I hover over an arrow on the inner content, the scroll bar appears as desired. However, it changes the content in a way that looks odd. Is there a solution to have a scroll bar on the inner co ...

Steps for extracting a portion of the current page's URL

Can someone help me extract a specific part of the current URL using JavaScript? The URL looks something like this: I need to isolate the number "3153038" from the URL and store it in a JavaScript variable. Thank you! ...

If the if logic in Express.js fails to function properly, it will consistently output the same message

Every time I run this code, it always displays the same message, even when I input different email addresses let message = ""; const findQuery = "select email from Users where email = ?"; const queryResult = await db.query(findQue ...

Using getStaticProps in Next.js to retrieve menu data and seamlessly integrate it into the layout

I have integrated Sanity.io as a backend for my project, specifically managing the data for my main menu in parent/children object arrays. While I am able to successfully fetch this data, I prefer to utilize getStaticProps to ensure that my site remains c ...