1. Einleitung
  2. Voraussetzungen
  3. 3D-Modell
  4. Vite & Three.JS
  5. index.html
  6. main.js
  7. Ergebnis

Animiertes 3D-Modell in Website
Mit ThreeJS

02. Januar 2023 · Erstellt mit Unterstützung von Chat GPT

In diesem Tutorial integrieren wir ein bestehendes 3D-Modell im gltf.-Format mit ThreeJS in eine Website und fügen eine dynamische Scroll-Animation hinzu. Hier eine Live-Demo des Ergebnisses.

Voraussetzungen

Um den Code zu verstehen, solltest du außerdem Grundkenntnisse in HTML, CSS und JavaScript besitzen

3D-Modell finden und herunterladen

Es gibt einige Platformen bei denen man hochwertige 3D-Modelle kostenlos herunterladen kann. Eine davon ist sketchfab. Schau dich um und finde das Modell, welches dir besonders gut gefällt. Wichtig ist, dass das 3D-Modell im .gltf-Format vorliegt!

Für mein Projekt habe ich das Datsun 240K GT-Modell von Karol Miklas ausgewählt.

Vite und Three.JS installieren

Vite benutzen wir als Build-Tool, um uns unseren Code während der Entwicklung als Ergebnis im Browser anzeigen zu lassen.

Öffne den Terminal und erstelle das Vite-Projekt, indem du folgenden Befehl ausführst:

$ npm create vite@latest

Du wirst aufgefordert einen Namen für das Projekt anzugeben. Danach sollst du dich für ein Framework entscheiden. Wähle VanillaJS und dann JavaScript aus.

Als nächstes installieren wir Three.JS, indem wir diesen Befehl ausführen:

$ npm install three

Erstelle als letzten Schritt der formalen Einrichtung noch einen Ordner mit dem Namen assets im Stammverzeichnis, um darin dein 3D-Modell zu speichern und, um später über main.js darauf zuzugreifen.

index.html

Im Stammverzeichnis wurde durch deine Vite-Initialisierung schon die index.html-Datei erstellt. Lösche den darin enthaltenen Code und füge den folgenden HTML-Code ein:

<!DOCTYPE html>
<html>
<head>
<title>My 3D Model</title>
</head>
<body>
    <div id="canvas">My 3D Model</div>
    <script src="/main.js"></div>
</body>
</html>

main.js

In der main.js-Datei, die ebenfalls im Stammverzeichnis erzeugt wurde, fügst du folgenden Code ein. Denke danach noch daran den vorgegebenen Pfad zur scene-gltf-Datei im Code durch den Pfad in deinem Projekt zu ersetzen:

  
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

//Scene
const scene = new THREE.Scene();

//Load Model - Specify path to YOUR scene.gltf file!
const glftLoader = new GLTFLoader();
const model = glftLoader.load('./assets/your_model/scene.gltf', (gltfScene) => {
  gltfScene.scene.translateX(1.5);
  gltfScene.scene.translateY(0.5);
  scene.add(gltfScene.scene);
  return gltfScene.scene;
});

//Sizes
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight,
}

//Light
const hemilight = new THREE.HemisphereLight(0xffeeb1, 0x080820, 25)
scene.add(hemilight)

const directlight1 = new THREE.DirectionalLight( 0xffffff)
directlight1.position.set(-6, 1, -6) //where does light shine on the object from
directlight1.intensity = 10
scene.add(directlight1)

const directlight = new THREE.DirectionalLight( 0xffffff)
directlight.position.set(-8, 1, 6) //where does light shine on the object from
directlight.intensity = 10
scene.add(directlight)

//Camera
const camera = new THREE.PerspectiveCamera(30, sizes.width/sizes.height, 0.1, 100) //wideness of cameraview (stay below 50)
camera.position.z = 8 // distance from object
camera.position.x = -1
camera.position.y = 0.5
scene.add(camera)

//Renderer
const canvas = document.querySelector('.webgl');
const renderer = new THREE.WebGL1Renderer({canvas})
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.toneMappingExposure = 2.3;
renderer.shadowMap.enabled = true;
renderer.setPixelRatio(2) //Avoids pixeling
renderer.setSize(sizes.width, sizes.height)
renderer.setClearColor( 0xffffff, 0);
renderer.render(scene, camera)

//Controls
const controls = new OrbitControls(camera, canvas)
controls.enabled = false;
controls.enableDamping = false
controls.enablePan = false
controls.enableZoom = false


//Resize
window.addEventListener("resize", () => {
  //update site
  sizes.width = window.innerWidth
  sizes.height = window.innerHeight

  //update camera
  camera.aspect = sizes.width/sizes.height
  camera.updateProjectionMatrix()
  renderer.setSize(sizes.width, sizes.height)
})

const loop = () => {
  controls.update()
  renderer.render(scene, camera)
  window.requestAnimationFrame(loop)
}

loop()

//Scroll Animation
function moveCamera() {
  const t = document.body.getBoundingClientRect().top;
  if( t >= -750 ){
    camera.position.z = 8 -  t * -0.023;
    camera.position.x = -1 -  t * -0.00046;
    camera.position.y = 0.5;
  }
  else if( t >= -1450 ){
    camera.position.z = (8 + 750 * -0.023) + (t + 750) * -0.02;
    camera.position.x = (-1 + 750 * -0.00046) + (t + 750) * + 0.003;
    camera.position.y = 0.5 + (t + 750) * -0.0002;
  }
  else{
    camera.position.x = (-1 + 750 * -0.00046) + (-1450 + 750) * + 0.003 + (t + 1450) * - 0.02;
    camera.position.z = (8 + 750 * -0.023) + (-1450 + 750) * -0.02 + (t + 1450) * - 0.002;
  }

}

document.body.onscroll = moveCamera;
moveCamera();
  

Ergebins anzeigen

Führen diesen Befehl aus, um dein Projekt zu starten und das 3D-Modell anzuzeigen.

$ npm run dev