aframe
コンポーネント
サーチ…
前書き
エンティティ・コンポーネント・システム・パターンでは、コンポーネントは、外観、動作、および/または機能性を追加するためにエンティティにプラグインする、再利用可能でモジュール式のデータ・チャンクです。
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 を呼び出し、 NodeList をArray 変換し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();