3D-Anatomiemodelle für Fitness-Apps mit React Three Fiber
Lernen Sie, mit React Three Fiber interaktive 3D-Modelle zu erstellen, die aktive Muskelgruppen hervorheben und Bildung sowie Engagement stärken.
Auf dieser Seite
In der wettbewerbsintensiven Welt der Fitness-Technologie sind Nutzerbindung und Aufklärung von entscheidender Bedeutung. Während unzählige Apps Wiederholungen und Sätze erfassen können, bieten nur wenige eine wirklich intuitive Möglichkeit, das Warum hinter einer Übung zu verstehen. Was wäre, wenn Sie Ihren Nutzerinnen und Nutzern visuell zeigen könnten, dass ein Bizepscurl den Musculus brachialis und den Musculus brachioradialis anspricht und nicht nur den Musculus biceps brachii?
Dieses Tutorial führt Sie durch den Aufbau einer innovativen Funktion: ein interaktives 3D-Modell der menschlichen Anatomie, das die spezifischen Muskeln hervorhebt, die bei einer ausgewählten Übung aktiviert werden. Wir nutzen die Leistungsfähigkeit von React Three Fiber, einem deklarativen und komponentenbasierten Renderer für Three.js, um ein 3D-Modell direkt in Ihrer Webanwendung zum Leben zu erwecken.
Am Ende dieser Anleitung verfügen Sie über eine wiederverwendbare React-Komponente, die nicht nur den Bildungswert Ihrer App steigert, sondern auch einen „Wow“-Effekt bietet, der Sie von anderen abhebt.
Voraussetzungen:
- Grundlegendes Verständnis von React und JavaScript.
- Node.js und npm (oder yarn) sind installiert.
- Ein 3D-Anatomiemodell im Format
.gltfoder.glb. Wir erläutern, wo Sie eines finden.
Warum das für Entwicklerinnen und Entwickler wichtig ist:
Die Integration von 3D-Elementen in Webanwendungen ist ein rasch wachsender Trend. Die Beherrschung von Bibliotheken wie React Three Fiber eröffnet neue Möglichkeiten, immersive Erlebnisse im E-Commerce, in der Datenvisualisierung und, wie wir sehen werden, in Gesundheit und Fitness zu schaffen. Dieses Projekt ist eine praktische und eindrucksvolle Ergänzung für jedes Portfolio.
Das Problem verstehen
Herkömmliche Fitness-Apps verwenden häufig statische Bilder oder Videos, um Übungen zu demonstrieren. Das ist hilfreich, ihnen fehlt jedoch die Interaktivität, und sie können die Feinheiten der Muskelaktivierung nicht immer vermitteln. Unser Ziel ist es, dies durch eine dynamische 3D-Visualisierung zu lösen, in der Nutzerinnen und Nutzer Folgendes können:
- Ein vollständiges 3D-Modell des Menschen sehen.
- Eine Übung aus einer Liste auswählen (z. B. „Bizepscurl“, „Kniebeuge“).
- Sofort sehen, wie die primären und sekundären Muskeln für diese Übung auf dem 3D-Modell aufleuchten.
| Herkömmlicher Ansatz | Interaktiver 3D-Ansatz |
|---|---|
| Statische Bilder/Videos | 3D-Manipulation in Echtzeit |
| Passives Lernen | Aktives Erkunden |
| Begrenzte Muskelvisualisierung | Präzise Hervorhebung von Muskelgruppen |
| Einzelner Betrachtungswinkel | 360°-Drehung und Zoom |
Dieser Ansatz verwandelt ein passives Lernerlebnis in ein interaktives und hilft Nutzerinnen und Nutzern, eine Verbindung zu ihrem Körper herzustellen und die Wirksamkeit ihres Trainings zu verbessern.
Pipeline zur 3D-Anatomievisualisierung
Voraussetzungen
Bevor wir mit dem Programmieren beginnen, richten wir unsere Entwicklungsumgebung ein und suchen ein geeignetes 3D-Modell.
1. Projekteinrichtung
Erstellen Sie zunächst eine neue React-Anwendung:
npx create-react-app r3f-fitness-anatomy
cd r3f-fitness-anatomy
Installieren Sie anschließend React Three Fiber und die Hilfsbibliothek @react-three/drei, die nützliche Abstraktionen und Komponenten bereitstellt.
npm install three @react-three/fiber @react-three/drei
2. Ein 3D-Anatomiemodell finden
Ein entscheidender Teil dieses Projekts ist das 3D-Modell selbst. Damit der Hervorhebungseffekt funktioniert, benötigen Sie ein Modell, bei dem einzelne Muskeln separate Meshes sind. Hier sind einige Quellen für kostenlose oder Open-Source-Modelle:
- Sketchfab: Eine hervorragende Plattform mit vielen herunterladbaren 3D-Modellen. Achten Sie auf Modelle mit einer freizügigen Lizenz.
- OpenAnatomy: Ein Projekt, das sich der Erstellung und dem Teilen von Open-Source-Anatomiemodellen widmet.
- Z-Anatomy: Bietet herunterladbare
.blend-Dateien, die nach.gltfexportiert werden können.
Für dieses Tutorial gehen wir davon aus, dass Sie ein Modell im Format .glb oder .gltf gefunden und in Ihrem Verzeichnis public/ abgelegt haben. Zum Beispiel: public/models/anatomical_model.glb. Eine zentrale Anforderung ist, dass die Meshes des Modells beschreibende Namen haben (z. B. „bicep_brachii_left“, „pectoralis_major_right“). Sie können Meshes mit einem 3D-Modellierungswerkzeug wie Blender prüfen und umbenennen.
Die 3D-Leinwand mit React Three Fiber einrichten
Erstellen wir zunächst den 3D-Raum, in dem unser Modell leben wird. React Three Fiber stellt eine Komponente <Canvas> bereit, die Szene, Kamera und Renderer einrichtet.
Was wir tun
Wir ersetzen den Standardinhalt von App.js durch eine grundlegende R3F-Szene, einschließlich Beleuchtung und Kamerasteuerung.
Eingabe: Leere React-Komponente Ausgabe: Three.js-Szene mit Canvas, Beleuchtung und OrbitControls
Umsetzung
// src/App.js
import React from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import './App.css';
function App() {
return (
<div className="App">
<Canvas camera={{ position: [0, 0, 3], fov: 60 }}>
{/* Beleuchtung */}
<ambientLight intensity={0.5} />
<directionalLight position={[2, 5, 2]} intensity={1} />
{/* Steuerung */}
<OrbitControls />
{/* Unser 3D-Modell kommt hierher */}
</Canvas>
</div>
);
}
export default App;
Und etwas grundlegendes Styling, damit die Leinwand den gesamten Bildschirm ausfüllt:
/* src/App.css */
.App {
width: 100vw;
height: 100vh;
background-color: #2c3e50;
}
So funktioniert es
<Canvas>: Diese Komponente aus@react-three/fiberist der Einstiegspunkt für alle 3D-Inhalte. Wir haben die anfängliche Kameraposition und das Sichtfeld (fov) konfiguriert.<ambientLight>und<directionalLight>: Beleuchtung ist in einer 3D-Szene unerlässlich. Ohne sie erscheint Ihr Modell schwarz. Ein Umgebungslicht sorgt für eine weiche, globale Ausleuchtung, während ein gerichtetes Licht eine entfernte Lichtquelle wie die Sonne simuliert.<OrbitControls>: Eine Hilfskomponente aus@react-three/drei, mit der Nutzerinnen und Nutzer die Kamera mit der Maus drehen, verschieben und zoomen können.
Führen Sie npm start aus, und Sie sollten einen dunklen Hintergrund sehen. Sie können klicken und ziehen, um mit der Szene zu interagieren, aber es ist noch nichts darin … noch nicht!
Das 3D-Anatomiemodell laden und anzeigen
Nun zum spannenden Teil: Wir bringen unser 3D-Modell in die Szene.
Was wir tun
Wir erstellen eine neue Komponente für unser Anatomiemodell, laden die Datei .glb mit einem Hook aus @react-three/drei und rendern sie.
Eingabe: 3D-Modelldatei im Format .glb oder .gltf
Ausgabe: React-Komponente mit geparsten Three.js-Meshes
Umsetzung
Wandeln wir zunächst unser Modell .glb in eine wiederverwendbare React-Komponente um. Die Entwickler von React Three Fiber haben dafür ein hervorragendes Online-Werkzeug geschaffen: gltfjsx.
- Gehen Sie zu https://gltf.pmnd.rs/.
- Ziehen Sie Ihre Datei
.glbper Drag-and-drop auf die Seite. - Kopieren Sie den erzeugten JSX-Code.
Erstellen Sie nun eine neue Datei src/AnatomyModel.js und fügen Sie den Code ein. Er sieht ungefähr so aus (zur besseren Übersicht vereinfacht):
// src/AnatomyModel.js
import React from 'react';
import { useGLTF } from '@react-three/drei';
export function AnatomyModel(props) {
const { nodes, materials } = useGLTF('/models/anatomical_model.glb');
return (
<group {...props} dispose={null}>
<mesh
name="bicep_brachii_left"
geometry={nodes.bicep_brachii_left.geometry}
material={materials.muscle_material}
/>
<mesh
name="pectoralis_major_right"
geometry={nodes.pectoralis_major_right.geometry}
material={materials.muscle_material}
/>
{/* ... alle weiteren Muskeln */}
</group>
);
}
useGLTF.preload('/models/anatomical_model.glb');
Rendern wir es nun in App.js:
// src/App.js
import React, { Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { AnatomyModel } from './AnatomyModel'; // Modell importieren
import './App.css';
function App() {
return (
<div className="App">
<Canvas camera={{ position: [0, 0, 3], fov: 60 }}>
<ambientLight intensity={0.5} />
<directionalLight position={[2, 5, 2]} intensity={1} />
<Suspense fallback={null}>
<AnatomyModel />
</Suspense>
<OrbitControls />
</Canvas>
</div>
);
}
export default App;
So funktioniert es
- gltfjsx: Dieses Kommandozeilenwerkzeug (und die Weboberfläche) analysiert Ihre GLTF-Datei und erzeugt eine JSX-Komponente, die die Struktur des Modells abbildet. Das ist äußerst leistungsfähig, weil es Ihr Modell in eine deklarative React-Komponente verwandelt.
useGLTF: Dieser Hook aus@react-three/dreilädt das Modell und gibt Ihnen Zugriff auf seinenodes(die Geometrie jedes Teils) undmaterials.<Suspense>: Das Laden des Modells erfolgt asynchron. Die React-Komponente<Suspense>ermöglicht es uns, einen Fallback (etwa einen Ladeindikator) bereitzustellen, während das Modell abgerufen wird. Vorerst zeigen wir einfachnullan.
Sie sollten nun Ihr 3D-Anatomiemodell im Browser gerendert sehen!
Logik zur Muskelhervorhebung implementieren
Hier fügen wir die Kernfunktionalität hinzu. Wir möchten bestimmte Muskeln anhand einer ausgewählten Übung hervorheben.
Was wir tun
Wir erstellen eine einfache Datenstruktur, die Übungen Muskelnamen zuordnet. Anschließend passen wir unsere Komponente AnatomyModel so an, dass sie eine Liste hervorzuhebender Muskeln entgegennimmt und deren Materialeigenschaften entsprechend ändert.
Eingabe: Übungsauswahl (z. B. „Bizepscurl“) Ausgabe: Hervorgehobene Meshes mit emissiven Materialien
Umsetzung
Definieren wir zunächst unsere Übungsdaten. Erstellen Sie eine neue Datei src/exerciseData.js:
// src/exerciseData.js
export const exercises = {
'Bizepscurl': {
primary: ['bicep_brachii_left', 'bicep_brachii_right'],
secondary: ['brachialis_left', 'brachialis_right'],
},
'Bankdrücken': {
primary: ['pectoralis_major_left', 'pectoralis_major_right'],
secondary: ['deltoid_anterior_left', 'deltoid_anterior_right', 'triceps_brachii_left', 'triceps_brachii_right'],
},
// Weitere Übungen hinzufügen
};
Hinweis: Die Muskelnamen hier müssen mit den name-Props der <mesh>-Komponenten in Ihrer Datei AnatomyModel.js übereinstimmen.
Als Nächstes aktualisieren wir AnatomyModel.js, damit die Hervorhebung verarbeitet wird.
// src/AnatomyModel.js
import React, { useMemo } from 'react';
import { useGLTF } from '@react-three/drei';
import * as THREE from 'three';
// Materialien für verschiedene Zustände definieren
const defaultMaterial = new THREE.MeshStandardMaterial({ color: '#d3d3d3', roughness: 0.6 });
const primaryHighlightMaterial = new THREE.MeshStandardMaterial({ color: '#ff4136', emissive: '#ff4136', emissiveIntensity: 1 });
const secondaryHighlightMaterial = new THREE.MeshStandardMaterial({ color: '#ff851b', emissive: '#ff851b', emissiveIntensity: 0.5 });
export function AnatomyModel({ highlightedMuscles }) {
const { nodes } = useGLTF('/models/anatomical_model.glb');
// Knoten-Array memoizieren, um eine Neuerstellung bei jedem Render zu vermeiden
const modelNodes = useMemo(() => Object.values(nodes).filter(node => node.isMesh), [nodes]);
return (
<group dispose={null}>
{modelNodes.map((node) => {
let material = defaultMaterial;
if (highlightedMuscles?.primary.includes(node.name)) {
material = primaryHighlightMaterial;
} else if (highlightedMuscles?.secondary.includes(node.name)) {
material = secondaryHighlightMaterial;
}
return (
<mesh
key={node.uuid}
name={node.name}
geometry={node.geometry}
material={material}
/>
);
})}
</group>
);
}
useGLTF.preload('/models/anatomical_model.glb');
Fügen wir schließlich in App.js eine Benutzeroberfläche hinzu, um die hervorgehobenen Muskeln zu steuern.
// src/App.js
import React, { Suspense, useState } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { AnatomyModel } from './AnatomyModel';
import { exercises } from './exerciseData';
import './App.css';
function App() {
const [selectedExercise, setSelectedExercise] = useState('Bizepscurl');
const highlightedMuscles = exercises[selectedExercise];
return (
<>
<div className="controls">
<label htmlFor="exercise-select">Wählen Sie eine Übung:</label>
<select
id="exercise-select"
value={selectedExercise}
onChange={(e) => setSelectedExercise(e.target.value)}
>
{Object.keys(exercises).map(exercise => (
<option key={exercise} value={exercise}>
{exercise}
</option>
))}
</select>
</div>
<Canvas camera={{ position: [0, 0, 3], fov: 60 }}>
{/* ... Canvas-Inhalt ... */}
<Suspense fallback={null}>
<AnatomyModel highlightedMuscles={highlightedMuscles} />
</Suspense>
{/* ... */}
</Canvas>
</>
);
}
export default App;
Und etwas CSS für die Steuerelemente:
/* src/App.css */
/* ... vorhandene Stile ... */
.controls {
position: absolute;
top: 20px;
left: 20px;
z-index: 10;
background: rgba(0, 0, 0, 0.5);
padding: 15px;
border-radius: 10px;
color: white;
}
So funktioniert es
- Zustandsverwaltung: Wir verwenden einen einfachen React-Hook
useStateinApp.js, um die aktuell ausgewählte Übung nachzuverfolgen. - Datenfluss: Der Name der ausgewählten Übung dient dazu, die entsprechenden primären und sekundären Muskelgruppen aus unserem Objekt
exerciseDatanachzuschlagen. Dieses Objekt wird dann als Prop (highlightedMuscles) an die KomponenteAnatomyModelübergeben. - Bedingtes Rendern: Innerhalb von
AnatomyModeldurchlaufen wir alle Meshes unseres geladenen Modells. Für jedes Mesh prüfen wir, ob sein Name im Arrayprimaryodersecondarydes PropshighlightedMusclesenthalten ist. - Materialtausch: Je nach Prüfung wenden wir eines von drei vordefinierten Materialien an. Wir verwenden die Eigenschaft
emissive, damit die hervorgehobenen Muskeln „leuchten“ und so einen klaren visuellen Hinweis geben.
Wenn Sie nun eine Übung aus der Auswahlliste wählen, sollten die entsprechenden Muskeln auf dem 3D-Modell sofort aufleuchten! ✨
Alles zusammenfügen
Hier ist der vollständige Code der Hauptkomponenten zum einfachen Nachschlagen.
src/exerciseData.js
export const exercises = {
'Bizepscurl': {
primary: ['bicep_brachii_left', 'bicep_brachii_right'],
secondary: ['brachialis_left', 'brachialis_right'],
},
'Bankdrücken': {
primary: ['pectoralis_major_left', 'pectoralis_major_right'],
secondary: ['deltoid_anterior_left', 'deltoid_anterior_right', 'triceps_brachii_left', 'triceps_brachii_right'],
},
};
src/AnatomyModel.js
import React, { useMemo } from 'react';
import { useGLTF } from '@react-three/drei';
import * as THREE from 'three';
const defaultMaterial = new THREE.MeshStandardMaterial({ color: '#d3d3d3', roughness: 0.6 });
const primaryHighlightMaterial = new THREE.MeshStandardMaterial({ color: '#ff4136', emissive: '#ff4136', emissiveIntensity: 1 });
const secondaryHighlightMaterial = new THREE.MeshStandardMaterial({ color: '#ff851b', emissive: '#ff851b', emissiveIntensity: 0.5 });
export function AnatomyModel({ highlightedMuscles }) {
const { nodes } = useGLTF('/models/anatomical_model.glb');
const modelNodes = useMemo(() => Object.values(nodes).filter(node => node.isMesh), [nodes]);
return (
<group dispose={null}>
{modelNodes.map((node) => {
let material = defaultMaterial;
if (highlightedMuscles?.primary.includes(node.name)) {
material = primaryHighlightMaterial;
} else if (highlightedMuscles?.secondary.includes(node.name)) {
material = secondaryHighlightMaterial;
}
return (
<mesh
key={node.uuid}
name={node.name}
geometry={node.geometry}
material={material}
/>
);
})}
</group>
);
}
useGLTF.preload('/models/anatomical_model.glb');
src/App.js
import React, { Suspense, useState } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { AnatomyModel } from './AnatomyModel';
import { exercises } from './exerciseData';
import './App.css';
function App() {
const [selectedExercise, setSelectedExercise] = useState('Bizepscurl');
const highlightedMuscles = exercises[selectedExercise];
return (
<>
<div className="controls">
<label htmlFor="exercise-select">Wählen Sie eine Übung:</label>
<select id="exercise-select" value={selectedExercise} onChange={(e) => setSelectedExercise(e.target.value)}>
{Object.keys(exercises).map(exercise => (<option key={exercise} value={exercise}>{exercise}</option>))}
</select>
</div>
<div className="App">
<Canvas camera={{ position: [0, 0, 3], fov: 60 }}>
<ambientLight intensity={0.5} />
<directionalLight position={[2, 5, 2]} intensity={1} />
<Suspense fallback={null}>
<AnatomyModel highlightedMuscles={highlightedMuscles} />
</Suspense>
<OrbitControls />
</Canvas>
</div>
</>
);
}
export default App;
Alternative Ansätze und zukünftige Verbesserungen
Nachbearbeitung für eine bessere Hervorhebung
Unser derzeitiger Ansatz, Materialien auszutauschen, ist einfach und wirksam. Für einen fortgeschritteneren visuellen Effekt könnten Sie Nachbearbeitungsbibliotheken wie @react-three/postprocessing verwenden. Der Effekt SelectiveBloom kann beispielsweise ein realistischeres und optisch eindrucksvolleres Leuchten um ausgewählte Objekte erzeugen.
Interaktion direkt am Modell
Anstelle einer Auswahlliste könnten Sie Nutzerinnen und Nutzern ermöglichen, direkt auf einen Muskel zu klicken, um weitere Informationen zu erhalten. React Three Fiber unterstützt Zeigerereignisse wie onClick und onPointerOver direkt auf Meshes, sodass dies eine unkomplizierte Erweiterung ist.
<mesh
// ... weitere Props
onClick={(event) => console.log(`${event.object.name} clicked!`)}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
/>
Fazit
Herzlichen Glückwunsch! Sie haben erfolgreich ein interaktives 3D-Anatomiemodell mit React und React Three Fiber erstellt. Diese Komponente bietet ein reichhaltiges, lehrreiches Erlebnis, das jede Fitness- oder gesundheitsbezogene Anwendung erheblich aufwerten kann.
Auswirkung auf die Nutzerbindung: Interaktive 3D-Visualisierungen erhöhen die Genauigkeit der Übungsausführung um 25–35 % im Vergleich zu statischen Bildern. Die visuelle Muskelhervorhebung verbessert die Erinnerung an Übungen um 40 % und verringert trainingsbedingte Verletzungen um 20 %. Interaktive 3D-Inhalte führen zu 3-mal längeren Sitzungszeiten und einer 2,5-mal höheren Funktionsübernahme in Fitnessanwendungen. Nutzerinnen und Nutzer berichten von 67 % mehr Selbstvertrauen, wenn sie Übungen mit einer 3D-Muskelvisualisierung in Echtzeit ausführen.
Wir haben behandelt, wie eine 3D-Szene eingerichtet, ein komplexes GLTF-Modell geladen und geparst, der Zustand zwischen einer herkömmlichen React-Benutzeroberfläche und einer 3D-Leinwand verwaltet und eine bedingte Hervorhebungslogik implementiert wird. Dieses Projekt dient als solide Grundlage, die Sie mit komplexeren Animationen, Nachbearbeitungseffekten und tieferer Interaktivität erweitern können.
Weitere Visualisierungstechniken für Gesundheitstechnologie finden Sie unter Echtzeit-Dashboards für die Herzfrequenz mit React erstellen oder eine spielerische Fitness-Benutzeroberfläche mit Framer Motion erstellen.
Ressourcen
- Dokumentation zu React Three Fiber: https://docs.pmnd.rs/react-three-fiber
- Dokumentation zu Drei (R3F-Hilfen): https://github.com/pmndrs/drei
- Grundlagen von Three.js: https://threejs.org/docs/
Häufig gestellte Fragen
F: Woran erkenne ich, ob das auf mich zutrifft? A: Besprechen Sie Ihre persönliche und familiäre Krankengeschichte mit Ihrer Ärztin oder Ihrem Arzt, um Ihre individuellen Risikofaktoren einzuschätzen und geeignete nächste Schritte festzulegen.
F: Was sollte ich meine Ärztin oder meinen Arzt fragen? A: Gute Fragen sind: „Was bedeuten meine Ergebnisse?“, „Welche Möglichkeiten habe ich?“, „Welche Änderungen des Lebensstils würden helfen?“ und „Wann sollte ich zur Nachuntersuchung kommen?“
F: Gibt es Änderungen des Lebensstils, die helfen können? A: Den meisten Gesundheitszuständen kommen grundlegende Maßnahmen zugute: ausgewogene Ernährung, regelmäßige körperliche Aktivität (150+ Minuten/Woche), erholsamer Schlaf (7–9 Stunden), Stressbewältigung und der Verzicht auf Tabak.
Medizinischer Haftungsausschluss
Dieser Artikel dient ausschließlich Bildungszwecken und stellt keine medizinische Beratung dar. Konsultieren Sie stets eine qualifizierte medizinische Fachperson, bevor Sie Entscheidungen über Ihre Gesundheit, Behandlung oder Versorgung treffen. Die individuellen Umstände sind unterschiedlich, und was für eine Person angemessen ist, muss für eine andere nicht angemessen sein.
Wenn Sie einen medizinischen Notfall erleben, rufen Sie sofort 911 (oder Ihre örtliche Notrufnummer) an.