3d render in section with grid template and resizing

Hello everyone! :smiley:

I am completely new in programming and I put myself in really taugh topic. I have decided to create random landing page in which I have section “New Cars”. I want to display in grid template 2 elements. First on the left is a text and second on the right is a 3d model of the car. I have tried a lot of solutions on this forum and on the Internet, but not one works for me.

Section looks like this:

My js code:

//3d render three.js

import * as THREE from "three";

import { OrbitControls } from "three/addons/controls/OrbitControls";

import { GLTFLoader } from "three/addons/loaders/GLTFLoader";

const renderer = new THREE.WebGLRenderer({ alpha: true });

//width of the rendered model

const smallerWidth = 700;

// //height of the rendered model

const smallerHeight = 350;

//setting smaller "window"

renderer.setSize(smallerWidth, smallerHeight);

renderer.setPixelRatio(window.devicePixelRatio);

document.getElementById("container3D").appendChild(renderer.domElement);

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(

45,

window.innerWidth / window.innerHeight,

0.1,

1000

);

camera.position.set(-300, 190, -310);

camera.lookAt(0, 0, 0);

const controls = new OrbitControls(camera, renderer.domElement);

controls.enableDamping = true; //making camera move smoother

controls.enablePan = false; //turning sidewats movement of camera

controls.minDistance = 235; //min distane which camera can be close to object

controls.maxDistance = 800; //max distane from camera to object

controls.minPolarAngle = 0.5; //min angle to limit the down movement of camera

controls.maxPolarAngle = 1.5; // max angle to limit the up movement of camera

controls.autoRotate = false; //turning off auto rotation of camera

controls.target = new THREE.Vector3(0, -50, 0); //points in which camera is looking

controls.update();

const topLight = new THREE.DirectionalLight(0xffffff, 5); //(control, intensity)

topLight.position.set(1500, 1500, 500); //top-left-ish

topLight.castShadow = true;

scene.add(topLight);

//Instantiate a lodaer for the .gltf file

const loader = new GLTFLoader().setPath("3d_render/cyberpunk_car_gltf/");

loader.load("scene.gltf", (gltf) => {

let object = gltf.scene;

object.position.set(0, 0, 0);

object.scale.set(0.85, 0.85, 0.85);

scene.add(object);

});

//ground

const planeGeometry = new THREE.CircleGeometry(220, 32);

const planeMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });

const plane = new THREE.Mesh(planeGeometry, planeMaterial);

plane.rotation.x = -Math.PI / 2;

plane.position.y = 0;

scene.add(plane);

//render the scene

function animate() {

console.log("Animation frame!");

requestAnimationFrame(animate);

//here we could add some code to update the scene, adding some automatic movement

renderer.render(scene, camera);

}

//add eventlistener to the window, so we can resize the window and the camera

window.addEventListener("resize", () => {

const width = window.innerWidth;

const height = window.innerHeight;

renderer.setSize(width, height);

camera.aspect = width / height;

camera.updateProjectionMatrix();

});

//start the 3d adnimation

animate();

Can anyone tell me where to look for a problem to solve?

fitting threejs in general is a little involved. i think you need resize observers (to figure out that the containing div has changed in size). grid needs overflow: hidden and the cell min-width min-height 0. the canvas also needs to be display: block or it will loop-grow the grid cell. once you have this it will also mess with your events, if the grid can scroll this isn’t even solvable with getBoundingClientRect and requires traversal similar to what jquery did.

stuff like this can suck the fun out of it. you could pair three to react, all of the boilerplate goes away. resize observers and css stuff is all taken care of, as well as events:

1 Like

hmm. i think i have set myself too difficult a task, because i am just learning front-end and react, vue, angular i don’t know. In that case, I’ll admit that I was thinking of reworking this element to render under the text describing the model.

No less, will I be able to insert this model in a carousel so that I can scroll through several models, or is this too difficult for a beginner level?

if you don’t have events it’s not hard. just apply the css props i mentioned. threes canvas is a dom element, you need to inform threejs of the size it takes which, if i remember correctly, requires a resize observer if the size is variable.

For someone who has the same problem.

I have found out the problem. In F12 i have noticed that when i was changing the screen size somehow the broswer was adding to element.style width and height in pixels. It was overwriting width 100% and height 100% in css. So i have added in my css “!important”:

      #container3D {
        position: relative;
        display: block;
        overflow: hidden;
        canvas {
          width: 100% !important;
          height: 100% !important;
        }
      }