three.js を使用してクールなアシッドスタイルの 3D ページ効果を実現します

three.js を使用してクールなアシッドスタイルの 3D ページ効果を実現します

この記事では、主にReact + three.jsテクノロジースタックを使用して3Dモデルの読み込み、3Dテキストの追加、アニメーションの増加、クリックインタラクションなどを行い、スタイルデザインと連携してデザインが充実した🤢`acidスタイルのページを実現する方法を紹介します。

背景

最近WebGLThree.jsの基礎知識を学んだので、最近流行の Acid Design スタイルを組み合わせて個人のホームページを装飾し、学んだ知識の一部をまとめたいと思います。この記事では主に、 React + three.jsテクノロジースタックを使用して3D模型読み込み、 3D文字の追加、アニメーションの増加、クリックインタラクションなどを行い、スタイルデザインと連携してデザイン性の高い🤢スタイルのページを実現する方法を紹介します。

基礎

Three.js

Three.js 、ネイティブWebGLパッケージに基づいてブラウザーで実行される3D引擎です。カメラ、ライト、影、マテリアル、その他のオブジェクトを含むさまざまな 3D シーンを作成するために使用できます。非常に広く使用されている 3D エンジンです。 three.js の公式中国語ドキュメントでさらに詳しく学ぶことができます。

アシッドデザイン

酸性設計という用語は、 Acid Graphicsを翻訳したもので、上世紀90年代のアシッド ハウス ミュージック、エレクトロニック ダンス ミュージック、ヒッピー文化に由来しています。デザインの分野では、このアシッド美学は自由的主張を持ち、独特のアシッドデザインスタイルを形成しています。

つまり、鮮艷高飽和度色の組み合わせ、黒とグレーを基調とした五彩斑斕的黑と彩度の高い熒光色で絵を飾ること、液態金屬玻璃鋁箔塑料などの未来的でクールなテクノロジー素材、隨機要素とグラフィックのレイアウト、幾何圖形の一定の重復、切断、組み合わせはすべて酸性のデザインスタイルです。アシッド スタイルは、音楽アルバムのカバー、ビジュアル ポスター、書籍や映画のカバー、Web デザインでも徐々に人気が出てきました。

成果を達成する

オンラインプレビュー: https://tricell.fun

成し遂げる

3Dモデル

シーンの初期化

🌏シーンを作成する

シーン = 新しい THREE.Scene();

📷カメラを初期化する

透視相機PerspectiveCamera4個パラメーターは、視野、アスペクト比、近い平面、遠い平面です。

カメラ = 新しい THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
// カメラの位置を設定します。camera.position.set(600, 20, -200);
// カメラは画面の中央に焦点を合わせます camera.lookAt(new THREE.Vector3(0, 0, 0));

💡光源を初期化する

半球光源HemisphereLightを追加: 屋外効果のためのより自然な光源を作成します

ライト = 新しい THREE.HemisphereLight(0xffffff, 0x444444);
ライトの位置を設定します(0, 20, 0);
シーンにライトを追加します。
ライト = 新しい THREE.DirectionalLight(0xffffff);
ライトの位置を設定します(0, 20, 10);
ライトをキャストします。
シーンにライトを追加します。

環境光AmbientLightを追加します:

var ambiColor = '#0C0C0C';
var ambientLight = new THREE.AmbientLight(ambiColor);
シーンにアンビエントライトを追加します。

アクセシビリティツールを追加する(オプション)

📦補助グリッドを追加する

GridHelperグリッド補助線を追加するために使用でき、また装飾にも使用できます。これはGridHelper(size, divisions, colorCenterLine, colorGrid)を通じて実装されます。

  • size : グリッドの幅、デフォルト値は10です。 divisions : 均等分割、デフォルト値は10です。
  • colorCenterLine : 中心線の色。デフォルト値は0x444444です。
  • colorGrid : グリッド線の色。デフォルト値は0x888888です。
var グリッド = new THREE.GridHelper(1000, 100, 0x000000, 0x000000);
グリッドの不透明度 = 0.1;
グリッドのマテリアルを透明にする
グリッドの位置を 0, -240, 0 に設定します。
シーンにグリッドを追加します。

📦カメラコントロールを追加する

カメラ コントロールOrbitControls使用すると、3 次元シーンを拡大縮小、移動、回転できます。基本的に変更されるのはシーンではなく、カメラのパラメータです。開発中にOrbitControls.jsを別途導入する必要があります。

コントロール = 新しい THREE.OrbitControls(カメラ、レンダラー.domElement);
コントロールのターゲットを設定します(0, 0, 0);
コントロールを更新します。

📦パフォーマンス表示プラグインを追加

statsThree.jsによって開発された補助ライブラリで、主にアニメーション実行時のフレーム数を検出するために使用されます。 stats.jsも別途インポートする必要があります。

統計 = 新しい統計();
コンテナに子要素を追加します。

モデルの読み込み

この記事で使用した扔鐵餅的人選手像の3Dモデルはthreedscans.comのもので、免費😄ダウンロードして使用することができます。この記事の最後には、複数の無料モデルダウンロードサイトが紹介されており、 200多頁無料モデルが掲載されています。興味があれば、お気に入りのモデルを選んでダウンロードして使用することができます。もちろん、モデリングスキルを持つ学生は、 blender3dmaxなどのプロフェッショナル モデリング ソフトウェアを使用して、お気に入りのモデルを生成することもできます。

objまたはfbxモデルをロードする

FBXLoader.jsまたはOBJLoader.jsを別途インポートする必要があります。.fbx .fbx.obj形式のモデルの読み込み方法は同じです。

// var loader = new THREE.FBXLoader();
var ローダー = new THREE.OBJLoader();
loader.load(モデル、関数(オブジェクト) {
  object.traverse(関数 (子) {
    子がメッシュである場合
      子.castShadow = true;
      子.receiveShadow = true;
    }
  });
  オブジェクトの回転y = Math.PI / 2;
  オブジェクトの位置を 0, -200, 0 に設定します。
  オブジェクトのスケールを0.32に設定します。
  モデル = オブジェクト;
  シーン.add(オブジェクト);
});

gltf モデルの読み込み

GLTFLoader.js別途導入する必要があります。.gltf .gltfのモデルの読み込み方法が若干異なります。モデルのトラバーサル オブジェクトとシーンへの最終的な追加はobjectではなくobject.sceneであることに注意してください。

var ローダー = new THREE.GLTFLoader();
loader.load(モデル、関数(オブジェクト) {
  object.scene.traverse(関数(子) {
    子がメッシュである場合
      子.castShadow = true;
      子.receiveShadow = true;
    }
  });
  object.scene.rotation.y = Math.PI / 2;
  オブジェクトのシーンの位置を設定します(0, -240, 0);
  オブジェクトのシーンスケールを設定します(0.33, 0.33, 0.33);
  モデル = オブジェクト.シーン;
  シーンを追加します。
});

メッシュを追加してモデルを読み込んだ後の効果を下図に示します。

ターンテーブルアニメーションを追加

requestAnimationFrameメソッドを使用してページを更新し、ターンテーブル アニメーション効果を追加します。 window.requestAnimationFrame()アニメーションを実行することをブラウザに伝え、次の再描画の前に指定されたコールバック関数を呼び出してアニメーションを更新するようにブラウザに要求します。このメソッドでは、ブラウザの次回の再描画の前に実行されるコールバック関数をパラメータとして渡す必要があります。

関数アニメーション(){
  アニメーションフレームをリクエストします(アニメーション化します);
  // ページが再描画されると、シーンの rotation.y が継続的に変更され、回転が実現されます。scene.rotation.y -= 0.015;
  レンダラー.レンダリング(シーン、カメラ);
}

クリックインタラクションの追加

Three.jsシーンで、モデルをクリックして情報を取得したり、その他の操作を実行したりする場合は、 Raycaster(光線投射)使用する必要があります。原理は、マウスをクリックした場所に光線を放射し、光線内のすべてのオブジェクトを記録することです。基本的な構文はRaycaster(origin, direction, near, far)です。

  • origin : 光線の開始点ベクトル。
  • direction : 光線の方向ベクトル。
  • near : 返される結果はすべてnearより遠いものになります。値は負の値にはできず、デフォルト値は0です。
  • far : 返される結果はすべてfarよりも近い必要があります。 nearより小さくすることはできません。デフォルト値無窮大

コード実装の基本的な手順は、画面上のマウスの座標を取得する画面座標を標準デバイス座標に変換する標準デバイス座標をワールド座標に変換するシーン内のマウスのワールド座標を取得するワールド座標とカメラに基づいてレイ キャスティング方向単位ベクトルを生成するレイ キャスティング方向単位ベクトルに基づいてレイ キャスター オブジェクトを作成する、です。

// raycaster とマウス変数を宣言します var raycaster = new THREE.Raycaster();
var マウス = new THREE.Vector2();
onMouseClick = イベント => {
  // マウスクリック位置の画面座標を、画面の中心を原点とし、値の範囲が -1 ~ 1 となる threejs の標準座標に変換します。
  マウスのx = (イベントのクライアントX / ウィンドウのインナー幅) * 2 - 1;
  mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
  // マウスポイントの位置と現在のカメラマトリックスに基づいてレイキャスターを計算します
  raycaster.setFromCamera(マウス、カメラ);
  // レイキャスターのラインとすべてのモデルとの交差点の配列コレクションを取得します。let intersects = raycaster.intersectObjects(scene.children);
  交差する長さが0より大きい場合
    アラート('HELLO WORLD')
    // 異なるメッシュをクリックして、トラバースすることでさまざまなインタラクションをトリガーできます。
    selectedObj = intersects[0].objectとします。
    選択されたオブジェクト名が「車」の場合
      アラート('車🚗')
    }
  }
}
window.addEventListener('click', onMouseClick, false);

3Dテキストを追加する

3D文字を追加するには、 TextGeometry(text : String, parameters : Object)を使用します。設定できるプロパティの説明は次のとおりです。

  • size : フォントサイズ。通常は大文字の高さです。
  • height : テキストの太さ。 weight : 値はnormalまたはboldで、太字にするかどうかを示します。
  • font : フォント。デフォルトはhelvetikerで、参照先のフォント ファイルに対応している必要があります。
  • style : 値はnormalまたはitalics 、斜体かどうかを示します。
  • bevelThickness : 面取りの厚さ。
  • bevelSize : ベベルの幅。
  • curveSegments : テキストの曲線をより滑らかにする円弧セグメントの数。
  • bevelEnabled : 面取り(エッジのベベル)を使用するかどうかを示すブール値。
var loader = new THREE.FontLoader();
loader.load('gentilis_regular.typeface.json', 関数(フォント) {
  var textGeo = new THREE.TextGeometry('HELLO WORLD', {
    フォント: フォント、
    サイズ: .8,
    高さ: .8,
    曲線セグメント: .05、
    ベベル厚さ: .05、
    ベベルサイズ: .05,
    ベベル有効: true
  });
  var textMaterial = new THREE.MeshPhongMaterial({ color: 0x03c03c });
  var mesh = new THREE.Mesh(textGeo, textMaterial);
  メッシュの位置を設定します(0, 3.8, 0);
  シーンを追加します(メッシュ);
}); 

最適化

現在、モデルの読み込みは基本的に完了していますが、 3Dモデルのボリュームは一般的に大きくなっています。展開後、Webページの読み込みが非常に遅く、ユーザーエクスペリエンスに影響していることがわかりました。モデルのサイズを縮小することが非常に重要です。インターネットで圧縮ツールを長い間検索したところ、大規模な3D建模軟件をインストールしなくても、 obj2gltfを使用すると、より大きなOBJ形式のモデルをgltfモデルに変換でき、モデルのボリュームを効果的に最適化し、Webページの読み込み速度を向上させることができることがわかりました。

インストール

npm をインストール obj2gltf --save

objモデルを次のディレクトリにコピーします

ノードモジュール\obj2gltf\bin

トランスコード命令を実行する

ノード obj2gltf.js -i デモ.obj -o デモ.gltf

図に示すように、上記の内容が表示され、トランスコードが完了します。変換前後のファイルサイズを比較すると、この例では、 kas.objの初期ファイルサイズは9.7Mですが、変換されたファイルkas.gltfはわずか4.6Mで、半分のサイズです。このとき、変換されたモデルがページに読み込まれ、肉眼ではモデル効果の変化はほとんど見えません。同時に、ページの読み込み速度が大幅に向上しました。

obj2gltf node服務を通じてモデルをリアルタイムで変換するためのライブラリとしても使用できます。興味のある学生は、記事の最後にあるリンクから詳細を学ぶことができます。
また、 blenderなどの3Dモデリング ソフトウェアを使用して、面數を減らし、縮小體積ことで、モデルを手動で圧縮して最適化することもできます。この最適化の効果はより顕著になります。

完全なコード

var モデル = require('@/assets/models/kas.gltf');
var コンテナ、統計、コントロール;
var カメラ、シーン、レンダラー、ライト、モデル;
クラスKasはReact.Componentを拡張します{
  与える () {
    戻る (
      <div id="kas"></div>
    )
  }
  コンポーネントマウント() {
    3 番目のメソッドは、次のとおりです。
  }
  initThree() {
    初期化();
    アニメーション化();
    関数init() {
      コンテナ = document.getElementById('kas');
      シーン = 新しい THREE.Scene();
      scene.fog = 新しい THREE.Fog(0xa0a0a0, 200, 1000);
      // パースペクティブ カメラ: 視野、アスペクト比、近い平面、遠い平面 camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
      カメラの位置を600, 20, -200に設定します。
      カメラ.lookAt(新しいTHREE.Vector3(0, 0, 0));
      // 半球光源: 屋外効果のためのより自然な光源を作成します。 light = new THREE.HemisphereLight(0xffffff, 0x444444);
      ライトの位置を設定します(0, 20, 0);
      シーンにライトを追加します。
      ライト = 新しい THREE.DirectionalLight(0xffffff);
      ライトの位置を設定します(0, 20, 10);
      ライトをキャストします。
      シーンにライトを追加します。
      // 周囲光 var ambiColor = '#0C0C0C';
      var ambientLight = new THREE.AmbientLight(ambiColor);
      シーンにアンビエントライトを追加します。
      // グリッド var grid = new THREE.GridHelper(1000, 100, 0x000000, 0x000000);
      グリッドの不透明度 = 0.1;
      グリッドのマテリアルを透明にする
      グリッドの位置を0, -240, 0に設定します。
      シーンにグリッドを追加します。
      // gltf モデルをロードします var loader = new THREE.GLTFLoader();
      loader.load(モデル、関数(オブジェクト) {
        object.scene.traverse(関数(子) {
          子がメッシュである場合
            子.castShadow = true;
            子.receiveShadow = true;
          }
        });
        object.scene.rotation.y = Math.PI / 2;
        オブジェクトのシーンの位置を設定します(0, -240, 0);
        オブジェクトのシーンスケールを設定します(0.33, 0.33, 0.33);
        モデル = オブジェクト.シーン;
        シーンを追加します。
      });
      レンダラー = 新しい THREE.WebGLRenderer({ アンチエイリアス: true、アルファ: true });
      レンダラーのピクセル比を設定します。
      レンダラーのサイズを設定します。
      レンダラー.setClearAlpha(0);
      レンダラー.shadowMap.enabled = true;
      コンテナに子要素を追加します。
      window.addEventListener('サイズ変更', () => {
        カメラのアスペクト比は window.innerWidth または window.innerHeight です。
        カメラの投影マトリックスを更新します。
        レンダラーのサイズを設定します。
      }、 間違い);
      統計 = 新しい統計();
      コンテナに子要素を追加します。
    }
    関数アニメーション(){
      var クロック = 新しい THREE.Clock()
      アニメーションフレームをリクエストします(アニメーション化します);
      var delta = clock.getDelta();
      シーン回転y -= 0.015;
      レンダラー.レンダリング(シーン、カメラ);
      統計情報を更新します。
    }
    // クリック イベントを追加します // raycaster およびマウス変数を宣言します var raycaster = new THREE.Raycaster();
    var マウス = new THREE.Vector2();
    関数 onMouseClick(イベント) {
      // マウスのクリック位置からレイキャスターが必要とするポイントの位置を計算します。画面の中心を原点とし、値の範囲は -1 ~ 1 です。
      マウスのx = (イベントのクライアントX / ウィンドウのインナー幅) * 2 - 1;
      mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
      // マウスポイントの位置と現在のカメラマトリックスに基づいてレイキャスターを計算します
      raycaster.setFromCamera(マウス、カメラ);
      // レイキャスター ラインとすべてのモデル間の交差点の配列コレクションを取得します。var intersects = raycaster.intersectObjects(scene.children);
      交差する長さが0より大きい場合
        アラート('HELLO WORLD')
      }
    }
    window.addEventListener('click', onMouseClick, false);
  }
}

その他のデザイン要素

この記事では、主に3D元素の読み込みについて紹介します。記事の長さと時間が限られているため (博主太懶😂 maybe 、他の要素の実装については詳しく説明しません ( 後でまとめるかもしれません )。興味のある学生は、他の偉大な巨匠による次の優れた記事を読むことができます。

流動的な背景

靜態液体背景は、SVG フィルターを使用して作成できます。SVG SVG filterを使用したパターンの作成 をお読みください。動態流体背景を作成するには、Three.js とネイティブ GLSL を組み合わせて使用​​できます。実装するには、CodePen のシェーダー テンプレートの例を参照してください。

メタル、ネオン、グリッチ効果などのアシッド効果フォントについては、私の別の記事「わずか数ステップの CSS でサイバーパンク 2077 スタイルの視覚効果を実現する」をお読みいただくか、デザイン生成をご利用ください。時間の制約により、このプロジェクトのメタル効果テキストとこの記事のバナー ヘッダーのテキストはすべて、オンライン アート フォント生成 Web サイトを使用して生成されています。興味のある学生は自分でデザインしてみることができます。

今後のさらなる最適化

  • #todoスタイルのリキッド背景の実装。
  • #todo 3D模型液体金属効果。

three.js優れたケースの推奨

最後に、皆さんが一緒に体験し、学べる素晴らしいthree.jsプロジェクトをいくつかお勧めしたいと思います。ページ インタラクション、ビジュアル デザイン、パフォーマンスの最適化など、これらのプロジェクトは究極の成果を達成しており、多くのことを学ぶことができます。

github ホームページ: 3D地球世界で人気のリポジトリをリアルタイムで表示します。

kodeclubs: 低ポリゴン3D城市サードパーソン ゲーム。

スニーカーディスプレイ:スニーカーを720度ダイナミックにディスプレイします。

砂の彫刻ダンス:砂の彫刻動物ダンサー。

Zenly ソフトウェア: Zenly Appの中国語ホームページ。

参考文献

3.js: https://threejs.org

obj2gltf: https://github.com/CesiumGS/obj2gltf

200 ページ以上の無料 3D モデル https://www.turbosquid.com

無料の 3D 彫像: https://threedscans.com

無料の 3D モデル: https://free3d.com

芸術的なフォントのオンライン生成: https://cooltext.com

アシッドデザインとは: https://www.shejipi.com/361258.html

著者: dragonir 記事URL: https://www.cnblogs.com/dragonir/p/15350537.html

three.js を使用してクールなアシッド スタイルの 3D ページを実装する方法についての記事はこれで終わりです。three.js アシッド スタイルの 3D ページに関するその他の関連コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Three.js が Facebook Metaverse 3D ダイナミック ロゴ効果を実現
  • three.js を使って立体的な矢印線を描く詳細な手順
  • three.js で 3D ダイナミック テキスト効果を実現する方法
  • 露滴アニメーション効果を実装するための Three.js サンプル コード
  • three.js でのマルチスレッドの使用とパフォーマンステストの詳細な説明
  • JavaScript Three.js でテキストを作成する最初の経験

<<:  MySQL ロック関連知識のまとめ

>>:  Docker-compose チュートリアルのインストールとクイックスタート

推薦する

docker compose を使用して consul クラスタ環境を構築する例

領事の基本概念サーバーモードとクライアントモードサーバー モードとクライアント モードは、consu...

Navicat は CSV データを MySQL にインポートします

この記事では、Navicatを使用してcsvデータをmysqlにインポートする方法を参考までに紹介し...

HTML要素のID属性とName属性の違い

今日、私は <a href="#13"></a> につい...

Vueのウェブページスクリーンショット機能の詳しい説明

最近、プロジェクトで写真をアップロードする要件があるのですが、顧客がアップロードする写真のサイズがま...

Docker プライベート ウェアハウスを構築する (自己署名方式)

作成したイメージを一元管理し、サービスの展開を容易にするために、プライベート Docker リポジト...

vue3 を使用したジグソーパズルゲームのリファクタリングの例

序文プロジェクト内のパズルゲーム(デジタル華容路とも呼ばれる)を再構築するのに 2 日かかりました。...

ARM64アーキテクチャでmysql5.7.22をインストールするプロセス全体

MySQLダウンロードアドレス: https://obs.cn-north-4.myhuaweicl...

koa2 サービスに SSL を設定する方法

I. はじめに1: SSL証明書私のドメイン名は Tencent Cloud にあります。第 3 レ...

Linuxはscpコマンドを使用してファイルをローカルコンピュータにコピーし、ローカルファイルをリモートサーバーにコピーします。

以下のように表示されます。リモート サーバーのファイルをローカルにコピーします。 scp -r -P...

MySQL のマスタースレーブレプリケーションと読み取り書き込み分離の原理と使用法の詳細な説明

この記事では、例を使用して、MySQL マスター/スレーブ レプリケーションと読み取り/書き込み分離...

Zabbix Agent2を使用してOracleデータベースを監視する方法

概要zabbix バージョン 5.0 以降では、zabbix-agent2 という新しい機能が追加さ...

Vueフィルターの使い方

目次概要フィルターの定義フィルターの使用カスタムグローバルフィルターローカルフィルター予防例1(ロー...

JS ES 新機能テンプレート文字列

目次1. テンプレート文字列とは何ですか? 2. 複数行のテンプレート文字列2.1 式付きテンプレー...

Linux FTP匿名アップロードとダウンロードが自動的に開始される問題を解決する

勉強や仕事で FTP サーバーを頻繁に使用する場合は、起動時に自動的に起動するように設定できます。設...

VMware 仮想化 KVM のインストールと展開のチュートリアルの概要

仮想化1. 環境セントオス7.3 selinuxとファイアウォールを無効にする2. 仮想化環境の構成...