TypeError: Cannot read property of undefined (read 'position') using ThreeJs
P粉760675452
P粉760675452 2024-04-01 12:01:52
0
1
418

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粉760675452
P粉760675452

reply all(1)
P粉239089443

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.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!