Use Cases (Diperbarui: 2/6/2026)

Three.js 3D dengan Claude Code: panduan Web UI praktis

Bangun viewer 3D dengan Claude Code dan Three.js, lengkap dengan resize, cleanup, review, dan use case nyata.

Three.js 3D dengan Claude Code: panduan Web UI praktis

Three.js membuat WebGL lebih mudah dipakai, tetapi UI 3D yang siap produksi bukan sekadar objek yang berputar. Kita tetap perlu mengatur kamera, pencahayaan, ukuran canvas, beban GPU di ponsel, cleanup saat komponen dilepas, dan fallback jika model gagal dimuat.

Claude Code sangat membantu karena bisa membuat fondasi Three.js dengan cepat. Namun prompt yang terlalu umum seperti “buat tampilan 3D yang keren” sering menghasilkan demo yang bagus secara visual tetapi rapuh: canvas kosong setelah layout berubah, renderer tetap hidup setelah pindah halaman, atau scene terlalu berat untuk perangkat mobile.

Artikel ini memberi contoh Vite + React + Three.js yang bisa disalin dan dijalankan, lalu menunjukkan cara meminta Claude Code melakukan review teknis sebelum fitur dipublikasikan.

Tentukan tujuan3D terlebih dahulu

Sebelum menulis kode, tentukan informasi apa yang harus didapat pengguna dari scene 3D. Untuk viewer produk, tujuannya bisa berupa warna, material, sisi belakang, dan kesan ukuran. Untuk visualisasi data, tujuannya mungkin melihat cluster, outlier, atau perubahan waktu. Untuk scene edukasi, tujuannya adalah mengarahkan perhatian ke bagian penting.

Prompt yang baik untuk Claude Code berisi batasan teknis, bukan hanya gaya visual.

Buat 3D product viewer dengan Vite + React + TypeScript + three.
Syarat:
- render canvas di dalam parent element
- ikuti resize parent container
- gunakan OrbitControls untuk rotate dan zoom
- dispose geometry, material, renderer, dan controls saat unmount
- batasi devicePixelRatio maksimal 2 untuk mobile
- kode bisa langsung disalin ke src/App.tsx

Batasan ini menjadi harness, yaitu kerangka kerja agar agent menghasilkan kode dengan aman. Harness membantu mencegah canvas kosong, render melebar, kebocoran resource setelah navigasi, dan beban GPU yang berlebihan. Untuk detail API, gunakan dokumentasi resmi Three.js dan halaman WebGLRenderer.

Setup minimal Vite/React

Mulailah dengan Three.js langsung di dalam React. React Three Fiber berguna, tetapi untuk tahap awal lebih mudah memahami lifecycle mentah: membuat renderer, menempelkan canvas ke DOM, mendengarkan resize, menjalankan animasi, lalu membersihkan resource.

npm create vite@latest three-claude-demo -- --template react-ts
cd three-claude-demo
npm i three
npm run dev
flowchart LR
  A["React component"] --> B["mount div"]
  B --> C["WebGLRenderer canvas"]
  C --> D["Scene"]
  D --> E["Camera and lights"]
  D --> F["Mesh and material"]
  C --> G["OrbitControls"]
  G --> H["resize and dispose"]

Viewer 3D yang bisa disalin

Salin kode berikut ke src/App.tsx. Kode ini membuat objek sederhana seperti produk, menambahkan pencahayaan dan kontrol kamera, mengikuti ukuran container, serta melepas resource Three.js saat komponen unmount.

import { useEffect, useRef } from "react";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import "./App.css";

export default function App() {
  const mountRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const mount = mountRef.current;
    if (!mount) return;

    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0xf6f7fb);

    const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
    camera.position.set(3.5, 2.2, 4.5);

    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.outputColorSpace = THREE.SRGBColorSpace;
    renderer.shadowMap.enabled = true;
    mount.appendChild(renderer.domElement);

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.minDistance = 2.5;
    controls.maxDistance = 8;
    controls.target.set(0, 0.4, 0);

    scene.add(new THREE.HemisphereLight(0xffffff, 0x7c8594, 1.6));

    const keyLight = new THREE.DirectionalLight(0xffffff, 2.4);
    keyLight.position.set(3, 5, 4);
    keyLight.castShadow = true;
    scene.add(keyLight);

    const productGeometry = new THREE.BoxGeometry(1.8, 1.2, 1.1, 4, 4, 4);
    const productMaterial = new THREE.MeshStandardMaterial({
      color: 0x2f6f73,
      roughness: 0.42,
      metalness: 0.08,
    });
    const product = new THREE.Mesh(productGeometry, productMaterial);
    product.castShadow = true;
    product.position.y = 0.75;
    scene.add(product);

    const floorGeometry = new THREE.CircleGeometry(2.2, 64);
    const floorMaterial = new THREE.MeshStandardMaterial({
      color: 0xd9dee8,
      roughness: 0.7,
    });
    const floor = new THREE.Mesh(floorGeometry, floorMaterial);
    floor.rotation.x = -Math.PI / 2;
    floor.receiveShadow = true;
    scene.add(floor);

    const resize = () => {
      const width = mount.clientWidth;
      const height = mount.clientHeight;
      if (width === 0 || height === 0) return;

      camera.aspect = width / height;
      camera.updateProjectionMatrix();
      renderer.setSize(width, height, false);
    };

    let frameId = 0;
    const clock = new THREE.Clock();

    const animate = () => {
      const elapsed = clock.getElapsedTime();
      product.rotation.y = elapsed * 0.45;
      product.rotation.x = Math.sin(elapsed * 0.8) * 0.08;
      controls.update();
      renderer.render(scene, camera);
      frameId = window.requestAnimationFrame(animate);
    };

    resize();
    animate();
    window.addEventListener("resize", resize);

    return () => {
      window.removeEventListener("resize", resize);
      window.cancelAnimationFrame(frameId);
      controls.dispose();

      scene.traverse((object) => {
        if (object instanceof THREE.Mesh) {
          object.geometry.dispose();
          const materials = Array.isArray(object.material)
            ? object.material
            : [object.material];
          materials.forEach((material) => material.dispose());
        }
      });

      renderer.dispose();
      renderer.domElement.remove();
    };
  }, []);

  return (
    <main className="viewerShell">
      <div className="copy">
        <p className="eyebrow">Three.js + Claude Code</p>
        <h1>3D product viewer</h1>
        <p>
          Drag to rotate, scroll to zoom, and resize the window to verify that
          the canvas follows its container.
        </p>
      </div>
      <div ref={mountRef} className="viewerStage" />
    </main>
  );
}

Tambahkan CSS berikut ke src/App.css. Tinggi .viewerStage wajib ada; tanpa tinggi, canvas bisa ada di DOM tetapi terlihat seperti layar kosong.

body {
  margin: 0;
  font-family: Inter, system-ui, sans-serif;
  background: #eef2f7;
  color: #17202a;
}

.viewerShell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(260px, 0.8fr) minmax(320px, 1.2fr);
  gap: 32px;
  align-items: center;
  padding: 40px;
  box-sizing: border-box;
}

.copy {
  max-width: 520px;
}

.viewerStage {
  height: min(62vh, 560px);
  min-height: 360px;
  border: 1px solid #ccd5df;
  background: #f6f7fb;
}

.viewerStage canvas {
  display: block;
}

@media (max-width: 760px) {
  .viewerShell {
    grid-template-columns: 1fr;
    padding: 24px;
  }

  .viewerStage {
    min-height: 300px;
  }
}

Minta Claude Code melakukan review

Setelah implementasi pertama, jangan hanya minta “rapikan desain”. Minta review risiko yang spesifik.

Review implementasi React + Three.js ini.
Periksa:
1. apakah canvas mengikuti ukuran parent container
2. apakah geometry, material, renderer, dan controls di-dispose saat unmount
3. apakah requestAnimationFrame berhenti
4. apakah devicePixelRatio aman untuk layar mobile padat
5. apakah akses window/document akan bermasalah di SSR seperti Next.js atau Astro
6. apakah kamera, cahaya, dan kontrol cocok untuk inspeksi produk
Berikan diff konkret dan checklist manual test.

Prompt ini membuat Claude Code bertindak sebagai reviewer. Kebocoran resource tidak selalu terlihat di screenshot, jadi lakukan navigasi beberapa kali lalu periksa Memory dan Performance di DevTools.

Tiga use case nyata

Use caseNilai dari 3DTugas untuk Claude Code
3D product viewerPembeli melihat warna, finishing, kedalaman, dan sisi belakangOrbitControls, variasi warna, preset cahaya, tes mobile
Visualisasi dataCluster, outlier, dan pergerakan waktu terlihat lebih jelaspoint cloud, bar 3D, transisi kamera, legenda
Portofolio atau edukasiStruktur dapat diputar sambil dijelaskanlabel, highlight bagian, posisi kamera terpandu

Untuk produk, 3D harus mengurangi keraguan pembelian. Untuk data, 3D harus membantu perbandingan; jika perspektif malah mengganggu, sediakan tampilan 2D. Untuk edukasi, rotasi bebas saja tidak cukup. Tambahkan urutan penjelasan, label, dan tombol kamera.

Kesalahan umum dan perbaikannya

MasalahPenyebab umumPerbaikan
Canvas kosongtinggi parent 0, kamera tidak mengarah, atau tidak ada cahayatetapkan tinggi CSS, cek camera position dan controls target
Scene melebar setelah resizecamera.aspect dan renderer size tidak diperbarui bersamapanggil camera.updateProjectionMatrix() dan renderer.setSize()
Halaman lambat setelah navigasiresource Three.js tidak di-disposetraverse scene saat unmount dan dispose geometry/material
Ponsel panaspixelRatio tinggi, shadow berat, geometry terlalu detailbatasi pixelRatio, kurangi shadow dan segment
Error SSRakses window/document saat render serverinisialisasi di useEffect atau komponen client-only

Saat debugging canvas kosong, sederhanakan dulu: background terang, satu cube, satu lampu, kamera yang jelas. Jangan debug GLB, HDR, post-processing, dan layout sekaligus.

Checklist rilis dan CTA

Sebelum rilis, uji di ponsel paling lemah yang ingin didukung. Periksa fps, panas, ukuran model, fallback jika WebGL gagal, dan teks penjelas untuk pengguna yang tidak bisa berinteraksi dengan canvas. Untuk arsitektur canvas, baca panduan Canvas dengan Claude Code. Untuk motion, lihat juga panduan animasi dengan Claude Code.

Claude Code Lab dapat membantu review 3D product viewer, visualisasi data WebGL, dan scene edukasi interaktif, termasuk training tim untuk prompt review. Siapkan target device, framework, format model, performance budget, dan alasan bisnis menggunakan 3D.

Hasil uji nyata

Saya menempelkan kode ini ke project Vite React TypeScript lalu menguji lebar desktop dan mobile. Tinggi eksplisit pada .viewerStage mencegah masalah canvas kosong. Batas devicePixelRatio ke 2 mengurangi kerja GPU yang tidak perlu pada layar padat, dan review dispose dengan Claude Code membantu menemukan risiko kebocoran resource sebelum fitur dianggap siap rilis.

#Claude Code #Three.js #3D #WebGL #frontend
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.