サーチ…


前書き

エンティティ・コンポーネント・システム・パターンでは、コンポーネントは、外観、動作、および/または機能性を追加するためにエンティティにプラグインする、再利用可能でモジュール式のデータ・チャンクです。

A-Frameでは、コンポーネントはシーン内の3Dオブジェクトであるエンティティを変更します。コンポーネントを組み合わせて複合オブジェクトを構築します。それらは、HTMLから宣言的に使用できるモジュールにthree.jsとJavaScriptコードをカプセル化しました。コンポーネントはCSSとほぼ同じです。

備考

定義ライフサイクルハンドラメソッド

スキーマが解剖学的構造であるため、ライフサイクルの方法は生理学である。スキーマはデータの形状を定義し、ライフサイクルハンドラメソッドはデータを使用してエンティティを変更します。ハンドラは通常、 Entity APIと対話します

メソッドの概要

方法説明
その中にコンポーネントの初期化時に1回呼び出されます。初期状態を設定し、変数をインスタンス化するために使用されます。
更新コンポーネントが初期化されたときと、コンポーネントのプロパティのいずれかが更新されたとき( setAttributeなど )の両方で呼び出されます。エンティティを変更するために使用されます。
除去するエンティティからコンポーネントが削除されたとき( removeAttributeなどを介して)、またはエンティティがシーンから切り離されたときに呼び出されます。エンティティへの以前のすべての変更を元に戻すために使用します。
ダニシーンの各レンダーループまたはティックで呼び出されます。継続的な変更やチェックに使用されます。
遊びますシーンやエンティティが背景や動的な動作を追加するたびに呼び出されます。コンポーネントが初期化されるときにも一度呼び出されます。動作の開始または再開に使用されます。
一時停止するシーンまたはエンティティが一時停止して背景​​や動的な動作を削除するたびに呼び出されます。コンポーネントがエンティティから削除されたとき、またはエンティティがシーンから切り離されたときにも呼び出されます。動作を一時停止するために使用されます。
updateSchema いずれかのコンポーネントのプロパティが更新されるたびに呼び出されます。スキーマを動的に変更するために使用できます。

コンポーネントのプロトタイププロパティ

メソッドの中で、私たちは、経由してコンポーネントのプロトタイプにアクセスすることができthis

プロパティ説明
this.data スキーマのデフォルト値、mixin、およびエンティティの属性から計算されたコンポーネントのプロパティを解析します。
this.el HTML要素としての[entity] [entity]への参照。
this.el.sceneEl HTML要素としての[シーン] [シーン]への参照。
this.id コンポーネントが[複数のインスタンス] [複数]を持つことができる場合、コンポーネントの個々のインスタンスのID(例えば、 sound__fooからのfoo )。

方法

。その中に ()

.init ()は、コンポーネントのライフサイクルの始めに一度呼び出されます。エンティティはコンポーネントのinitハンドラを呼び出すことができます:

  • コンポーネントがHTMLファイル内のエンティティに静的に設定され、ページがロードされたとき。
  • コンポーネントがsetAttributeを介して添付エンティティに設定されている場合。
  • コンポーネントが添付されていないエンティティに設定され、そのエンティティがappendChildを介してシーンにアタッチされるとき。

initハンドラはしばしば次の目的で使用されます。

  • 初期状態と変数を設定する
  • バインドメソッド
  • イベントリスナーをアタッチする

たとえば、カーソルコンポーネントのinitは、状態変数を設定し、メソッドをバインドし、イベントリスナーを追加します。

AFRAME.registerComponent('cursor', {
  // ...
  init: function () {
    // Set up initial state and variables.
    this.intersection = null;
    // Bind methods.
    this.onIntersection = AFRAME.utils.bind(this.onIntersection, this);
    // Attach event listener.
    this.el.addEventListener('raycaster-intersection', this.onIntersection);
  }
  // ...
});

.update(oldData)

.update (oldData)は、コンポーネントのライフサイクルの開始時を含め、コンポーネントのプロパティが変更されるたびに呼び出されます。エンティティはコンポーネントのupdateハンドラを呼び出すことができます:

  • init ()が呼び出された後、コンポーネントのライフサイクルの始めに。
  • コンポーネントのプロパティが.setAttribute更新される.setAttribute

updateハンドラは、多くの場合次の目的で使用されます。

  • ほとんどの作業はthis.dataを使用してエンティティに変更をthis.dataます。
  • 1つ以上のコンポーネントプロパティが変更されるたびにエンティティを変更します。

エンティティへの粒状修正が[相違取得] [差分]により行うことができる現在のデータセット( this.data更新(前の前のデータセットを有する) oldData )。

A-Frameは、コンポーネントのライフサイクルの開始時およびコンポーネントのデータが変更されるたびに(たとえば、 setAttribute結果として.update()呼び出します。更新ハンドラは、多くの場合this.dataを使用してエンティティを変更します。更新ハンドラは、最初の引数を介してコンポーネントのデータの前の状態にアクセスできます。コンポーネントの以前のデータを使用して、細かい更新を行うために変更されたプロパティを正確に伝えることができます。

たとえば、 可視コンポーネントのupdateによって、エンティティの可視性が設定されます。

AFRAME.registerComponent('visible', {
  /**
   * this.el is the entity element.
   * this.el.object3D is the three.js object of the entity.
   * this.data is the component's property or properties.
   */
  update: function (oldData) {
    this.el.object3D.visible = this.data;
  }
  // ...
});

.remove()

.remove ()は、コンポーネントがエンティティから切り離されるたびに呼び出されます。エンティティはコンポーネントのremoveハンドラを呼び出すことができます:

  • コンポーネントがremoveAttributeを介してエンティティから削除されたとき。
  • エンティティがシーンから切り離されたとき( removeChild

removeハンドラは、多くの場合次の目的で使用されます。

  • エンティティに対するすべてのコンポーネントの変更を削除、元に戻す、またはクリーンアップします。
  • イベントリスナーを切り離します。

たとえば、[ライトコンポーネント] [ライト]が削除されると、ライトコンポーネントはエンティティに以前設定したライトオブジェクトを削除し、シーンから削除します。

AFRAME.registerComponent('light', {
  // ...
  remove: function () {
    this.el.removeObject3D('light');
  }
  // ...
});

.tick(time、timeDelta)

.tick ()は、シーンのレンダーループのティックまたはフレームごとに呼び出されます。シーンはコンポーネントのtickハンドラを呼び出します:

  • レンダリングループの各フレームで。
  • 毎秒60〜120回のオーダー。
  • エンティティまたはシーンが一時停止していない場合(インスペクタが開いているなど)
  • エンティティがまだシーンにアタッチされている場合

tickハンドラはしばしば次の目的で使用されます。

  • 各フレームまたは一定間隔でエンティティを継続的に変更します。
  • 条件の投票。

tickハンドラには、ミリ秒( time )単位でのシーンのグローバルな稼働時間と、最後のフレーム( timeDelta )からの時間差(ミリ秒単位)が提供されます。補間に使用することも、指定された間隔でtickハンドラの部分だけを実行することもできます。

たとえば、 追跡されたコントロールコンポーネントは、コントローラのアニメーションを進行させ、コントローラの位置と回転を更新し、ボタンの押下をチェックします。

AFRAME.registerComponent('tracked-controls', {
  // ...
  tick: function (time, timeDelta) {
    this.updateMeshAnimation();
    this.updatePose();
    this.updateButtons();
  }
  // ...
});

.pause()

エンティティまたはシーンが一時停止すると、 .pause ()が呼び出されます。エンティティはコンポーネントのpauseハンドラを呼び出すことができます:

  • コンポーネントが削除される前に、 removeハンドラが呼び出される前。
  • エンティティがEntity.pause ()一時停止している場合
  • シーンがScene.pause ()一時停止しているScene.pause ()インスペクタが開いているなど)

pauseハンドラは、多くの場合次の目的で使用されます。

  • イベントリスナーを削除します。
  • 動的な動作の可能性を排除します。

たとえば、 サウンドコンポーネントサウンドを一時停止し、イベントでサウンドを再生したイベントリスナーを削除します。

AFRAME.registerComponent('sound', {
  // ...
  pause: function () {
    this.pauseSound();
    this.removeEventListener();
  }
  // ...
});

。遊びます ()

.play ()は、エンティティまたはシーンが再開するときに呼び出されます。エンティティはコンポーネントのplayハンドラを呼び出すことができます:

  • コンポーネントが最初にアタッチされるとき、 updateハンドラが呼び出された後。
  • エンティティが一時停止された後、 Entity.play ()再開されたEntity.play ()
  • シーンが一時停止した後、 Scene.play ()再開したScene.play ()

playハンドラは、多くの場合、

  • イベントリスナーを追加します。

たとえば、 サウンドコンポーネントサウンドを再生し、イベントでサウンドを再生するイベントリスナを更新します。

AFRAME.registerComponent('sound', {
  // ...
  play: function () {
    if (this.data.autoplay) { this.playSound(); }
    this.updateEventListener();
  }
  // ...
});

.updateSchema(data)

.updateSchema ()が定義されている場合は、スキーマを動的に変更する必要があるかどうかを確認するために、更新ごとに.updateSchema ()が呼び出されます。

updateSchemaハンドラは、多くの場合次のupdateSchema使用されます。

  • 通常はプロパティの値に応じて、スキーマを動的に更新または拡張します。

たとえば、 ジオメトリコンポーネントは、 primitiveプロパティが変更されて、異なるタイプのジオメトリのスキーマを更新するかどうかを確認します。

AFRAME.registerComponent('geometry', {
  // ...
  updateSchema: (newData) {
    if (newData.primitive !== this.data.primitive) {
      this.extendSchema(GEOMETRIES[newData.primitive].schema);
    }
  }
  // ...
});

成分プロトタイプ法

.flushToDOM()

文字列化のCPU時間を節約するため、A-Frameは実際のDOMでのコンポーネントのシリアライズされた表現のみをデバッグモードで更新します。 flushToDOM()を呼び出すと、コンポーネントのデータが手動でシリアル化され、DOMが更新されます。

document.querySelector('[geometry]').components.geometry.flushToDOM();

カスタムAフレームコンポーネントを登録する

AFRAME.registerComponent(name、definition)

Aフレームコンポーネントを登録します。コンポーネントを使用する前に登録する必要があります。 。 HTMLファイルからの意味では、コンポーネントは前もって整列していなければなりません

  • {string} name - コンポーネント名。コンポーネントのパブリックAPI(HTML属性名で表される)。
  • {Object}定義 - コンポーネント定義。スキーマおよびライフサイクルハンドラメソッドが含まれています。

あなたのjsファイルにfooのコンポーネントを登録する(例:foo-component.js)

AFRAME.registerComponent('foo', {
  schema: {},
  init: function () {},
  update: function () {},
  tick: function () {},
  remove: function () {},
  pause: function () {},
  play: function () {}
});

シーン内のfooコンポーネントの使用

<html>
  <head>
    <script src="aframe.min.js"></script>
    <script src="foo-component.js"></script>
  </head>
  <body>
    <a-scene>
      <a-entity foo></a-entity>
    </a-scene>
  </body>
</html>

コンポーネントHTMLフォーム

コンポーネントは、1つまたは複数のコンポーネントプロパティの形式でデータのバケットを保持します。コンポーネントはこのデータを使用してエンティティを変更します。エンジンコンポーネントを考えると、馬力やシリンダーなどのプロパティを定義することができます。

HTML属性はコンポーネント名を表し、これらの属性の値はコンポーネントデータを表します。

単一プロパティコンポーネント

コンポーネントが単一プロパティのコンポーネントである場合、そのデータが単一の値で構成され、HTMLではコンポーネントの値は通常のHTML属性のように見えます。

<!-- `position` is the name of the position component. -->
<!-- `1 2 3` is the data of the position component. -->
<a-entity position="1 2 3"></a-entity>

複数プロパティコンポーネント

コンポーネントが複数プロパティのコンポーネントである場合、データは複数のプロパティと値で構成され、HTMLではコンポーネントの値はインラインCSSスタイルに似ています。

<!-- `light` is the name of the light component. -->
<!-- The `type` property of the light is set to `point`. -->
<!-- The `color` property of the light is set to `crimson`. -->
<a-entity light="type: point; color: crimson"></a-entity>

コンプナント・スキーマ・オブジェクトの定義

スキーマは、コンポーネントのプロパティまたはプロパティを定義および記述するオブジェクトです。スキーマのキーはプロパティの名前で、スキーマの値はプロパティのタイプと値を定義します(複数プロパティコンポーネントの場合)。

コンポーネントにスキーマを定義する

AFRAME.registerComponent('bar', {
  schema: {
    color: {default: '#FFF'},
    size: {type: 'int', default: 5}
  }
}

定義済みのスキーマのデフォルトを上書きする

<a-scene>
  <a-entity bar="color: red; size: 20"></a-entity>
</a-scene>

単一プロパティスキーマ

コンポーネントは、単一のプロパティコンポーネント(1つの匿名値で構成)または複数のプロパティコンポーネント(複数の名前付き値で構成される)のいずれかになります。 A-Frameは、スキーマの構造に基づいて、コンポーネントが単一プロパティ対複数プロパティかどうかを推測します。

単一プロパティのコンポーネントのスキーマには、 typeキーまたはdefaultキーが含まれています。スキーマの値は、オブジェクトではなくプレーンな値です。

AFRAME.registerComponent('foo', {
  schema: {type: 'int', default: 5}
});
<a-scene>
  <a-entity foo="20"></a-entity>
</a-scene>

A-Frameのコンポーネントスキーマプロパティタイプ

プロパティタイプは主に、スキーマが各プロパティのDOMからの受信データをどのように解析するかを定義します。解析されたデータは、コンポーネントのプロトタイプのdataプロパティを介して利用可能になります。以下に、A-Frameの組み込みプロパティタイプを示します。

物件のタイプ説明デフォルト値
アレイ カンマで区切られた値を配列に変換します(つまり、 "1, 2, 3" to ['1', '2', '3']) []
資産 一般資産を指すURLの場合。 url(<url>)形式で文字列からURLを解析できます。値が要素IDセレクタ( #texture )の場合、このプロパティ型はgetElementByIdおよびgetAttribute('src')を呼び出してURLを返します。 assetプロパティタイプは、XHRを扱うか、MediaElementsを直接返すように変更されてもされなくてもよい(例えば、 <img>要素)。 ''
オーディオ assetプロパティタイプと同じ構文解析。オーディオアセットを表示するためにAフレームインスペクタによって使用される可能性があります。 ''
ブール値 ブール値(つまり、文字列に解析して"false"をfalseに、他のすべてtruthyを)。
現在、解析は行われません。主にAフレームインスペクタがカラーピッカーを表示するために使用します。また、カラーアニメーションにはカラータイプを使用して作業する必要があります。 #FFF
int 呼び出しparseInt (例えば、 "124.5"124 )。 0
地図 assetプロパティタイプと同じ構文解析。テクスチャアセットを表示するためにAフレームインスペクタで使用される可能性があります。 ''
モデル assetプロパティタイプと同じ構文解析。モデルアセットを提示するためにAフレームインスペクタで使用される可能性があります。 ''
parseFloat呼び出しparseFloat (例えば、 '124.5'から'124.5' )。 0
セレクタ querySelector呼び出しquerySelector (例: "#box"から<a-entity id="box"> )。 ヌル
selectorAll querySelectorAllを呼び出し、 NodeListArray変換しNodeList (例: ".boxes"から[<a-entity class = "boxes"、...])。 ヌル
文字列 解析は一切行いません。 ''
vec2 {x, y}オブジェクトに2つの数を解析します(たとえば、 1 -2から{x: 1, y: -2} {x:0、y:0}
vec3 {x, y, z}オブジェクトに3つの数字を解析します(例: 1 -2 3から{x: 1, y: -2, z: 3} {x:0、y:0、z:0}
vec4 {x, y, z, w}オブジェクトに4つの数値を解析します(例えば、 1 -2 3 -4.5から{x: 1, y: -2, z: 3, w: -4.5} {x:0、y:0、z:0、w:0}
プロパティ型推論

スキーマは、デフォルト値のみが与えられたプロパティ型を推測しようとします:

schema: {default: 10}  // type: "number"
schema: {default: "foo"}  // type: "string"
schema: {default: [1, 2, 3]}  // type: "array"

プロパティーの種類が指定されている場合、スキーマは提供されない場合、デフォルト値を設定します。

schema: {type: 'number'}  // default: 0
schema: {type: 'string'}  // default: ''
schema: {type: 'vec3'}  // default: {x: 0, y: 0, z: 0}
カスタムプロパティタイプ

また、 type代わりにparse関数を提供することで、独自のプロパティ型やパーサを定義することもできます。

schema: {
  // Parse slash-delimited string to an array 
  // (e.g., `foo="myProperty: a/b"` to `['a', 'b']`).
  myProperty: {
    default: [],
    parse: function (value) {
      return value.split('/');
    }
  }
}

コンポーネントのメンバーおよびメソッドへのアクセス

コンポーネントのメンバーとメソッドには、 .componentsオブジェクトのエンティティからアクセスできます。エンティティのコンポーネントのマップからコンポーネントを参照すると、コンポーネントの内部にアクセスできるようになります。このコンポーネント例を考えてみましょう。

AFRAME.registerComponent('foo', {
  init: function () {
    this.bar = 'baz';
  },
  qux: function () {
    // ...
  }
});

barメンバーとquxメソッドにアクセスしましょう:

var fooComponent = document.querySelector('[foo]').components.foo;
console.log(fooComponent.bar);
fooComponent.qux();


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow