What is the best way to align geometry at the bottom of the screen in Three.js while still preserving its aspect

I recently started using Threejs and encountered an issue with positioning geometry. I'm trying to place the geometry at the bottom with half of it cut off, so only half should be visible. However, when I use position.setY(-300), the geometry moves down but also stretches. I'm not sure what I'm doing wrong or how to position the geometry correctly without distorting its aspect ratio. Can someone help me solve this problem?

Here is the link to the fiddle and code: link to fiddle

var camera, scene, renderer;
var geometry, material, muesum;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.z = 600;

  scene = new THREE.Scene();

  geometry = new THREE.IcosahedronGeometry(350, 2);

  material = new THREE.MeshPhongMaterial({
    wireframe: true,
  });

  muesum = new THREE.Mesh(geometry, material);

  scene.add(muesum);
  muesum.position.setY(-300);

  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

}

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

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {

  requestAnimationFrame(animate);

  muesum.rotation.x += 0.001;
  muesum.rotation.y += 0.002;
  renderer.clear();
  renderer.render(scene, camera);

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>

Answer №1

When an object appears to be "losing its aspect ratio," it is due to the perspective projection of a large object being very close to the camera.

To avoid this effect, one can use the OrthographicCamera, which creates an orthographic projection matrix and projects the scene parallel to the viewport.

Check out the Example:

var camera, scene, renderer;
var geometry, material, mesh;

init();
animate();

function updateCameraProjection() {
    var aspect    = window.innerWidth / window.innerHeight;
    var wndHeight = 700;
    camera.right  = aspect*wndHeight/2
    camera.left   = -camera.right;
    camera.top    = wndHeight/2;
    camera.bottom = -camera.top;
    camera.near   = 1;
    camera.far    = 1000;
    camera.updateProjectionMatrix();
}

function init() {

  camera = new THREE.OrthographicCamera();
  updateCameraProjection();
  camera.position.z = 500;

  scene = new THREE.Scene();

  geometry = new THREE.IcosahedronGeometry(350, 2);

  material = new THREE.MeshPhongMaterial({
    wireframe: true,
  });

  mesh = new THREE.Mesh(geometry, material);

  scene.add(mesh);
  mesh.position.setY(camera.bottom);

  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

}

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

function onWindowResize() {
    updateCameraProjection();
    mesh.position.setY(ontop);
    renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {

  requestAnimationFrame(animate);

  mesh.rotation.x += 0.001;
  mesh.rotation.y += 0.002;
  renderer.clear();
  renderer.render(scene, camera);

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>

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

Assigning a session variable through a dropdown selection

Currently, I am working on a custom WordPress theme that involves setting a session variable based on the value selected from a dropdown box. This session variable is then used to determine which container should be loaded. The code snippet below shows whe ...

Dynamically sending data to child components in Vue.js

I'm currently working on a progress bar implementation where the progress status is determined by the submitAction method. The value for the progress bar is constantly being updated in this method. Here's my code: 1. Parent Component <templa ...

How can we use response.render in Express.js to render HTML on the client side?

I have set up a simple Express.js application with the following routes: router.get('/', function(req, res){ res.render('login'); }); Everything is working fine - when I log into the main page on my localhost, the HTML fro ...

Send a signal to a space, leveraging the distinct characteristics of each socket as input parameters

I am looking to send a function to a group of sockets, with each socket receiving the function along with a specific parameter unique to that particular socket. In my coding scenario, this distinctive variable represents the player's number. As socke ...

How to effectively implement addEventListener() / attachEvent()?

Can anyone provide guidance on how to correctly use addEventListener and attachEvent? window.onload = function (myFunc1) { /* do something */ } function myFunc2() { /* do something */ } if (window.addEventListener) { window.addEventListener('load ...

Is it possible to personalize the Facebook like box appearance?

Is there a way to modify the number of feeds and enable auto scroll feature in a Facebook likebox? I've been experimenting with the code snippet below but have hit a roadblock. <div id="fb-root"></div><script>(function(d, s, id) {va ...

Contains a D3 (version 3.4) edge bundle chart along with a convenient update button for loading fresh datasets

I am looking to update my D3 (v3.4) edge bundling chart with a new dataset when a user clicks an 'update' button. Specifically, I want the chart to display data from the data2.json file instead of data1.json. Although I have started creating an u ...

The Unicode range [uXXXX] in Regex is not recognized during the AJAX request

I am currently facing an issue with removing control characters (e.g. \u0005) from the ajax response string. I have implemented a regular expression for this purpose: msg = msg.replace(/[\x00-\x1F\x7F-\x9F]/g, ''); Inter ...

Is there a way to convert an array into an object where the first value in the array becomes the name and the properties are an array of the remaining values within subarrays?

Looking to efficiently group elements of a multidimensional array with an unknown list, and transform it into an object while removing duplicate values in the first element of each subarray: For instance, here's the initial array: const arr = [[a, 1 ...

How can I effectively test the success of a form submission in next.js using jest for unit testing?

At the moment, I am in the process of developing a unit test for a registration form within my application. The main objective of this test is to ensure that the registration process can be executed successfully without actually saving any new data into th ...

What are the steps for transmitting an array of data to Parse Cloud Code?

Trying to send an array of contact emails as a parameter in Cloud Code function for Parse, here is how I am doing it: HashMap<String, ArrayList<String>> params = new HashMap<>(); ArrayList<String> array = new ArrayList<>(); a ...

What could be causing my router UI in angular.js to malfunction?

Having an issue with routing not functioning as intended, here is the relevant code: $urlRouterProvider. otherwise('/list'); $stateProvider. state('home', { abstract: true, views: { 'header': { templateUrl: &apos ...

Action type is not recognized: modification

After browsing through multiple forums, I haven't found a solution that works for my particular issue with my VueJS app. The problem arises when I try to input something in my first component. Below is the code snippet: main.js import Vue from &apos ...

Is there a way to create a new prettyphoto window by clicking on a link within the original prettyphoto window?

I have an HTML table that is dynamically constructed on the server side using AJAX. The table is displayed using prettyphoto, everything works fine up to this point. However, the last column of the table contains a link that should open an image using pret ...

How to include an array of data in an $http request using AngularJS

I am trying to store data in an array to the $http service in AngularJS. The way I am currently adding them to the service is as follows (and it is functioning correctly): var inputValueArray = new Array($scope.formdata); Currently, I am able to retriev ...

Click on the hyperlinks one by one that trigger ajax events

There is a feature on the popular social media platform reddit.com where you can load more comments by clicking a link. I understand that comments may be hidden for performance reasons, but I would like to automatically expand all comments without having t ...

What could be causing this JSON object error I'm experiencing?

res.send({ customerDetails:{ fName, lName, }, applicantDetails:{ [ {primaryApplicant:{fName1,lName1}}, {secondaryApplicant:{fName2,lName2}}, {thirdA ...

Displaying image while processing substantial ajax data

I implemented code to toggle the display of a loading image on my web page while making ajax requests. $(document).ajaxStart(function(){ $("#please_wait").css("display","block"); }); $(document).ajaxComplete(function(){ $("#please_wait").css(" ...

Conflicting TypeScript enum types: numbers and numbers in NestJS/ExpressJS

Incorporating types into my NestJS server has been a priority. After creating a controller (a route for those who prefer Express), I attempted to define the type for params: public async getAllMessages( @Query('startDate', ValidateDate) start ...

Leveraging client-side routes in conjunction with page templates retrieved from Contentful

Objective In an effort to restrict access to certain content under a specific URL (/dashboard), I am exploring the use of client-only routes. This content, sourced from Contentful and utilizing a page template, will follow a route structure like {MYDOMAIN ...