1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【個人開発】Next.jsでのWebサイト制作 #3 トップページ紹介とThree.jsによる3Dモデルの実装紹介

Last updated at Posted at 2024-07-26

Next.jsでのWebサイト制作 #3 では、トップページ紹介とThree.jsによる3Dモデルの実装紹介をしたいと思います。

トップページ紹介

トップページは以下のようになっています。(ぜひアクセスしてご覧ください。)

  • メイン画像+メインメッセージ 部分
    image.png

  • メッセージ部分
    image.png

  • ブログ最新記事部分
    image.png

メイン画像+メインメッセージ 部分

この部分では、画像スライドショーとアニメーションによるメッセージの出現を実装しています。
ここで使用している技術は、以下過去記事にて紹介させていただいておりますので、ここでの説明は割愛させていただきます。

ブログ最新記事部分

ブログ最新記事部分では、Blogページ(microCMSからデータを取得)にて掲載している記事のうち、最新のものを表示する仕様となっています。

ここで使用している技術は、Blogページの回で紹介予定ですので、今回は割愛させていただきます。

メッセージ部分

今回の記事は、このメッセージ部分における、3Dモデル「動く地球」の実装方法をメインに紹介します。
3Dモデルは、Three.jsという Javascriptライブラリを用いて実装しています。

タイトルなし.gif

Three.jsとは?

Three.jsは、Webブラウザ上で3Dモデルを簡単に表示できるJavaScriptライブラリです。

JavaScriptの基本的な知識があれば、Three.jsを用いてWebブラウザ上に3Dモデルや3Dアニメーションを簡単に表示できるようになります。

もともと、WebGLという3Dモデルを扱う技術があったそうですが、かなり難易度が高いようです。(私は全く学んだことありません。。)

Three.jsを使うことでWebGLを使うよりも圧倒的に簡単に実装できます。

実装方法

3Dモデルのダウンロード

今回は以下サイトから3Dモデルを「GLTF」フォーマットでダウンロードし、public/modelsに格納しました。

インストール

npm install three

TypeScript使用時は型ファイルのインストールも必要

npm install @type/three

実装

以下が実際のコードです。
処理ごとの意味、説明は、コメントに記載してあります。

私自身、初めてThree.jsを扱ったため、わからないことが多く、「ググって。。。うまく動かないところを修正して。。。」の繰り返しでした。
そのため、あまり詳しい説明ができていませんが、ご了承ください。。。。

import { useEffect, useRef } from "react";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

// 3Dモデル

function Earth() {
 // 3Dモデルを表示したい部分のDOM要素をuseRefでもってくる
 const canvasRef = useRef<HTMLCanvasElement | null>(null);

 // useEffect内に3Dモデルの設定を書くことで、レンダリング時に3Dモデルが生成されるようになる。
 // Three.jsで3Dモデルを出力するには、以下に定義する、scene, camera, rendererの3つのオブジェクトが最低限必要となる。
 useEffect(() => {
   const canvas = canvasRef.current as HTMLCanvasElement;

   const sizes = {
     width: 350,
     height: 370,
   };

   // scene(3D空間全体の情報をもつオブジェクト)
   const scene = new THREE.Scene();

   // camera(3Dモデルをどのように画面に映すかを、カメラをのぞいた時のようなイメージで定義できるオブジェクト)
   const camera = new THREE.PerspectiveCamera(
     85, //垂直視野
     sizes.width / sizes.height, //アスペクト比
     0.1, //Near(奥行きの手前側)
     1000 //Far(奥行きの最奥)→NearとFarの間にあるものが画面に映し出される。
   );
   camera.position.set(0, 0, 2); //カメラ自体の位置(x軸, y軸, z軸)

   // renderer(レンダリング設定)
   const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer({
     canvas: canvas, //useRefでとってきた要素。ここに3Dモデルがレンダリングされる。
     antialias: true, //3Dモデルの端を滑らかにする。
     alpha: true, //背景の設定(透明にしたい場合はtrue)
   });
   renderer.setSize(sizes.width, sizes.height); //ここの記述はお決まり。
   renderer.setPixelRatio(window.devicePixelRatio); //ここの記述はお決まり。

   // ライトの設定(この設定がないと映らない3Dモデルがある)
   const light = new THREE.PointLight(0xffffff, 1); //特定の方向からのライト(第1引数:光の色、第2引数:光の強さ)
   light.position.set(0, 1, 1); //sceneから見たライトの位置 (第1引数:x軸、第2引数:y軸、第3引数:z軸)
   scene.add(light); //sceneにライトを紐付け
   const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); //全方向からのライト≒モデルそのものの光度(第1引数:光の色、第2引数:光の強さ)
   scene.add(ambientLight); //sceneにライトを紐付け

   // GLTFモデルのインポート
   let model: THREE.Object3D<THREE.Object3DEventMap>; // モデルを格納する変数
   const gltfLoader = new GLTFLoader();
   gltfLoader.load("/models/earth.gltf", (gltf) => {
     model = gltf.scene;
     model.scale.set(0.14, 0.14, 0.14); //modelの大きさ(スケール)を設定
     scene.add(model); //sceneにmodelを紐付け
   });

   // アニメーション
   const tick = () => {
     if (model) {
       // modelを回転させる
       model.rotation.y += 0.0025; // Y軸周りに毎フレーム回転(数字はスピード)
     }
     renderer.render(scene, camera); // 現在のシーンをカメラの視点からレンダリング(描画)(ここの記述はお決まり。)
     requestAnimationFrame(tick); // ブラウザに次の再描画のフレームでtick関数を呼び出すように要求(ここの記述はお決まり。)
   };
   tick(); //初回のアニメーションフレームを開始するためにtick関数を一度呼び出す(ここの記述はお決まり。)
 }, []);

 return (
   <canvas
     id="canvas"
     ref={canvasRef}
     className="  mx-auto  xl:ml-[67%]"
   ></canvas>
 );
}

export default Earth;

上記実装により、3DモデルをWebブラウザに表示することができます。

最後に

今回は、トップページ(特に3Dモデル部分)について紹介させていただきました。
Three.jsはWebGLに比べると簡単にかけるものとは言われていますが、私としては十分難しかったです。。笑

次回は、Garalleyページ、Blogページについて、紹介させていただきたいと思います。

最後までお読みいただきありがとうございました!!

p.s.
Qiitaの記事をより多くの人に読んでもらう方法を教えてください!
タイトルを検索されやすいようなタイトルにする、くらいはやってみようと思っていますが、その他何かありましたらご教授いただければ幸いです!!!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?