PractiX Code Lab

【Next.js × three.js】ポートフォリオに3D表現を導入するために考えたこと

Share this post

🚪はじめに

管理人のTKGです。

ポートフォリオサイトを作るにあたり、「3D表現を取り入れたい」という構想があり、今回はNetx.jsと相性の良い、three.jsを使って**3D表現を実装しました。

今回はポートフォリオサイトの3D演出の実装について、導入背景、選定理由、実装手順についての学びを記事にまとめました。


🎯想定読者

  • Webポートフォリオにインパクトある演出を取り入れたい方
  • three.jsをポートフォリオに活かしたいが、何から始めるか迷っている方
  • Next.js × three.js の組み合わせ事例を探している方

📘本記事でわかること

  • ポートフォリオに3D表現を取り入れる際の考え方
  • Next.jsとthree.jsの連携ポイント
  • 3D導入で気を付けたこと・やってよかったこと

🔍コンテンツ

1. 🎯なぜ3D表現を取り入れようと思ったか

ポートフォリオの制作方針を考える中で、

以下の通り「やりたいこと」を整理しました。

  • 他のポートフォリオと差別化したい
  • スキル(Next.js, three.js, GSAPなど)を具体的にアピールしたい
  • ユーザー体験に「インタラクティブ性」や「楽しさ」を加えたい

特に「静的なページ」ではなく、触れて動かせる楽しさを表現しました。


2. 🧩技術選定:Next.jsとthree.jsの組み合わせ

選んだ技術スタックは以下:

  • Next.js:サイト全体のベース、ルーティング、パフォーマンス最適化
  • three.js:3Dモデル・3Dアニメーションの表現
  • React-Three-Fiber(r3f):React上でthree.jsを使いやすくするラッパー
  • Drei:よく使うthree.jsオブジェクトを簡単に扱う補助ライブラリ

この組み合わせにした理由は:

  • Next.jsが持つ高速表示・SEOの強みを活かしながら
  • Reactのコンポーネント管理の思想で、three.jsを安全に扱いたかったため

結果、パフォーマンスと自由度を両立できる構成を選びました。


3. 📝具体的に想定した演出

要件定義段階では、次のような演出をリストアップしていました。

  • トップページ中央に回転する立方体(マウス連動)
  • スクロールに合わせて変化するパーティクルアニメーション(2D) ⇒後日スクロール要素は取り下げ代わりにパララックス表現を取り入れました。
  • 制作物ページへの遷移時に、3Dオブジェクトをフェードアウト/インさせる演出

最終的には、**初回訪問時にローディング演出(2D)**も導入しました。※後日記事化予定


4. 🚀Next.js × three.jsの導入手順

ポートフォリオサイトにthree.jsを導入するにあたり、基本的な導入手順は以下のような流れになります。


✅ Step 1:Next.jsプロジェクトを作成

npx create-next-app@latest my-portfolio
cd my-portfolio

まずはNext.jsベースのプロジェクトを立ち上げます。


✅ Step 2:three.jsをインストール

npm install three

必要に応じて、React用ラッパーの@react-three/fiberや補助ライブラリ@react-three/dreiもインストールします。

npm install @react-three/fiber @react-three/drei


✅ Step 3:Canvasコンポーネントを作成

three.jsで描画を行うため、Canvasコンポーネントを設置します。 (React-Three-Fiberを使う場合)

例:

mport { Canvas } from '@react-three/fiber'

export default function ThreeScene() {
  return (
    <Canvas>
      {/* ここにオブジェクトやライトなどを追加 */}
    </Canvas>
  )
}


✅ Step 4:オブジェクト・ライト・カメラを設置

3D空間に配置する要素(例:Box、Sphere、Lightなど)を追加します。

例:

import { Mesh } from '@react-three/fiber'

function Box() {
  return (
    <mesh>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color="orange" />
    </mesh>
  )
}

Canvas内に配置:

<Canvas>
  <ambientLight />
  <pointLight position={[10, 10, 10]} />
  <Box />
</Canvas>


✅ Step 5:アニメーションやインタラクションを追加

  • フレームごとに回転や移動アニメーションを追加
  • マウス連動やスクロール連動でインタラクション演出も可能

React-Three-Fiberでは、useFrameフックを使ってアニメーション制御ができます。

例:

import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'

function RotatingBox() {
  const meshRef = useRef()

  useFrame(() => {
    if (meshRef.current) {
      meshRef.current.rotation.x += 0.01
      meshRef.current.rotation.y += 0.01
    }
  })

  return (
    <mesh ref={meshRef}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color="skyblue" />
    </mesh>
  )
}


※上記では画面中央に「水色(skyblue)」の立方体(ボックス)が表示され、そのボックスが、ゆっくり回転し続ける。背景は特に設定していないため、デフォルトの黒背景となっています。


5. 🔧Next.jsとthree.js連携で工夫したポイント

ポートフォリオにthree.jsを導入するにあたり、次のような工夫をしました。


✅ パフォーマンスチューニング

最初は、自作した3Dオブジェクトを回転させることも考えていました。

しかし、描画時の読み込み遅延や、制作・学習コストの高さを考慮し、

まずはシンプルな立方体オブジェクトを使った表現に絞りました。

それでも以下の工夫を取り入れることで、初学者感をなるべく抑えました。

  • three.js上で簡単に作れるオブジェクトを選択
  • オブジェクトの色や回転速度、回転軸に変化をつけることで、単調さを軽減
  • インタラクション性(マウス連動や動きの演出)を取り入れて、見た目に"おもしろさ"を付加

✅ 軽量化

また、ページ全体の表示速度を落とさないように、

three.jsに関しても必要な機能のみを読み込む設計を意識しました。

  • three.jsライブラリ全体をまるごと読み込まず、必要最低限のモジュールだけを使う
  • @react-three/fiber@react-three/dreiを活用して、無駄なコード記述を減らす
  • ツリーシェイキング(未使用コードの除去)を意識したビルド設計

これにより、表示パフォーマンスをできるだけ損なわずに3D表現を組み込むことができました。


🔥ポイントまとめ

工夫内容
オブジェクト設計シンプルな立方体+色・回転などで工夫
インタラクション性動きや反応を取り入れて「おもしろさ」を演出
パフォーマンス意識必要機能のみを使い、軽量化

6. 🧠やってよかったこと・注意すべきこと

✅ 良かったこと

  • 最初に3D表現を導入する目的を文章化しておいたことで、品質の妥協点を見いだせた点。
  • あらかじめ、ユーザーと自分のやりたい表現について優先度を整理していたため、妥協点を模索しやすかった点。

🚀成果物リンク

👉Takashi Sekiguchi | Portfolio


🏁おわりに

実際に3D表現を入れるにあたり、完成度を上げようとするとどこまでもこだわれてしまうので、どこまでのクオリティまでが必須なのかという、品質レベルでもあらかじめ妥協点を設定しておくことが重要と感じました。

「なぜその機能が必要なのか?それは必須の機能なのか?」という点を明確にして、開発に取り組むことが重要だと感じました。

今回の取り組みが、これからポートフォリオを開発する方の参考になれば嬉しいです!

Share this post