Home  >  Q&A  >  body text

TypeError: Cannot read property of undefined (read 'position') using ThreeJs

I'm trying to integrate a 3D model into the background of the hero section of my website. It works, it's just that when I change the window size manually, the 3D model doesn't adapt to the new size. Another issue that may be related to the first one is that I get this error message in the console, which refers to line 69 of the code in the "two.js" file: In the console I get this error message:

My first task is to solve the problem of 3D models not adapting to the screen size. As for the error message, it doesn't really matter if it still works. But ideally, two people can solve both problems.

Do you have any ideas?

import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

const heroSection = document.querySelector("#hero-section");
heroSection.appendChild(renderer.domElement);

// Importation du model 3D
const loader = new GLTFLoader();
let model;
loader.load(
  "./scene.gltf",
  function (gltf) {
    model = gltf.scene;

    scene.add(gltf.scene);
  },
  undefined,
  function (error) {
    console.error(error);
  }
);

//Control des mouvements
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableZoom = false;

const ambientLight = new THREE.AmbientLight(0xffffff);
const light = new THREE.AmbientLight(0x404040);
scene.add(ambientLight, light);

// position de la camera
camera.position.set(0, 1, 5);
// camera.position.set(0, 4, 8);
controls.update();

function animate() {
  requestAnimationFrame(animate);

  model.position.y = -2;
  controls.update();
  renderer.render(scene, camera);
}

animate();
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: 16px;
  scroll-behavior: smooth; /* permet un scroll automatique souple video : 1h 07mn 50 */
  scroll-padding-top: 100px; /* On lui dit : arrête le scroll auto à 100px pour tenir compte de la hauteur de la navbar. 
  ("PROJECTES" appaît en haut et sous la navbar quand on click sur le lein "Projects" de la navbar.) */
}

body {
  background-color: #000;
  font-family: "roboto", sans-serif;
  overflow-x: hidden;
}

nav {
  position: fixed;
  top: 0;
  width: 100%;
  height: 100px;
  padding: 20px 10vw;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 9;
  transition: 0.4s; /* pour le background noire - vidéo : 1h 09 */
}

nav.bg {
  /* Voir vidéo : 1h 09 */
  background-color: #000;
}

.logo {
  height: 50px;
}

.links-container {
  display: flex;
  list-style: none;
  gap: 10px;
}

.links {
  color: #fff;
  text-decoration: none;
  text-transform: capitalize;
  padding: 10px 20px;
  transition: 0.5s;
}

.links:hover {
  opacity: 0.5;
}

/* hero-section */
#hero-section {
  position: relative;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
}

#hero-section canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

.hero-content {
  position: relative;
  z-index: 2;
}

.hero-headline {
  font-family: "sahitya", serif;
  font-size: 4.5rem;
  text-align: center;
}

.hero-secondary-line {
  text-align: center;
  margin: 25px 0 50px;
  font-size: 1.2rem;
}

.btn {
  padding: 15px 30px;
  width: fit-content; /*(pas utile pur moi : explication : https://css-tricks.com/almanac/properties/w/width/#:~:text=the%20fit-content%20value*/
  background-color: #000;
  color: #fff;
  text-decoration: none;
  text-transform: capitalize;
  display: block; /*pour faire fonctionner 'margin:auto' */
  margin: auto;
}

.btn.light {
  background-color: #fff;
  color: #000;
}

.btn.transparent {
  background: transparent;
  border: 2px solid;
}
<!DOCTYPE html>
<html lang="en" theme="light">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Three JS Personal Portfolio</title>

    <!-- google font CDN -->

    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;300;400;500;600;700;800;900&family=Roboto+Slab:wght@100;300;500;600;700;800;900&family=Roboto:wght@400;700&family=Sahitya&display=swap" rel="stylesheet" />

    <!-- font awesome CDN -->

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />

    <!-- local CSS file(s) -->

    <link rel="stylesheet" href="style.css" />

    <!-- Tree Js -->
    <script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@latest/build/three.module.js",
          "three/addons/": "https://unpkg.com/three@latest/examples/jsm/"
        }
      }
    </script>
  </head>

  <body>
    <header>
      <nav>
        <img src="img\Logo.png" alt="" class="logo" />
        <ul class="links-container">
          <li class="link-item"><a href="#hero-section" class="links">Home</a></li>
          <li class="link-item"><a href="#Projects-section" class="links">Projects</a></li>
          <li class="link-item"><a href="#" class="links">About</a></li>
          <li class="link-item"><a href="#" class="links">Contact</a></li>
        </ul>
      </nav>
      <!-- hero section -->
      <main id="hero-section">
        <div class="hero-content">
          <h1 class="hero-headline">Take your business onligne</h1>
          <p class="hero-secondary-line">The only person you need to help you with your business</p>

          <a href="#" class="btn">Let's chat</a>
        </div>
        <!-- Position du canvas dans le navigateur -->
      </main>
    </header>
   </body>

P粉760675452P粉760675452181 days ago422

reply all(1)I'll reply

  • P粉239089443

    P粉2390894432024-04-02 09:03:49

    The reason it doesn't resize is because of an error. It's trying to update your model's position, but at this point the model isn't defined yet, so it errors out and doesn't move any further.

    I think you end up calling the animate() function before the async file loading is complete. Because the rest of the code runs when the object loads, it gets to the last line, runs the animate function, and fails because the model is undefined at this point. If you want this to happen after the model is loaded, you need to move it into the success function.

    reply
    0
  • Cancelreply