元件
定義生命週期處理程式方法
模式是解剖學,生命週期方法是生理學; 模式定義資料的形狀,生命週期處理程式方法使用資料來修改實體。處理程式通常會與 Entity API 進行互動。
方法概述
方法 | 描述 |
---|---|
init |
初始化元件時呼叫一次。用於設定初始狀態和例項化變數。 |
update |
在元件初始化時以及任何元件的任何屬性更新時(例如,通過 setAttribute ) 呼叫。用於修改實體。 |
remove |
從元件中刪除元件時(例如,通過 removeAttribute )或當實體與場景分離時呼叫。用於撤消對實體的所有先前修改。 |
tick |
在每個渲染迴圈或場景的刻度上呼叫。用於連續更改或檢查。 |
play |
每當場景或實體播放時呼叫以新增任何背景或動態行為。初始化元件時也呼叫一次。用於啟動或恢復行為。 |
pause |
每當場景或實體暫停以刪除任何背景或動態行為時呼叫。從實體中刪除元件或從場景中分離實體時也會呼叫。用於暫停行為。 |
updateSchema |
每當更新任何元件的屬性時呼叫。可用於動態修改架構。 |
元件原型屬性
在這些方法中,我們可以通過 this
訪問元件原型:
屬性 | 描述 |
---|---|
this.data |
根據模式預設值,mixins 和實體的屬性計算解析的元件屬性。 |
this.el |
將[entity] [entity]引用為 HTML 元素。 |
this.el.sceneEl |
將[scene] [scene]引用為 HTML 元素。 |
this.id |
如果元件可以具有[多個例項] [多個],則元件的單個例項的 ID(例如,來自 sound__foo 的 foo )。 |
方法
init
.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
更新元件的屬性時。
update
處理程式通常用於:
- 使用
this.data
進行大部分修改實體的工作。 - 只要一個或多個元件屬性發生更改,就修改實體。
對實體的細粒度修改可以通過在更新(oldData
)之前使用先前的資料集[diffing] [diff]當前資料集(this.data
)來完成。
A-Frame 在元件生命週期的開始和每次元件的資料發生變化時呼叫 .update()
(例如,由於 setAttribute
)。更新處理程式通常使用 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 ()
暫停場景時(例如,開啟 Inspector)。
pause
處理程式通常用於:
- 刪除事件偵聽器。
- 消除任何動態行為的可能性。
例如,聲音元件將暫停聲音並刪除會在事件上播放聲音的事件偵聽器:
AFRAME.registerComponent('sound', {
// ...
pause: function () {
this.pauseSound();
this.removeEventListener();
}
// ...
});
.play()
當實體或場景恢復時,呼叫 .play ()
。實體可以呼叫元件的 play
處理程式:
- 首次連線元件時,呼叫
update
處理程式後。 - 當實體暫停但隨後用
Entity.play ()
恢復。 - 當場景暫停但隨後用
Scene.play ()
重新開始。
play
處理程式通常用於:
- 新增事件偵聽器。
例如,聲音元件將播放聲音並更新將在事件上播放聲音的事件偵聽器:
AFRAME.registerComponent('sound', {
// ...
play: function () {
if (this.data.autoplay) { this.playSound(); }
this.updateEventListener();
}
// ...
});
.updateSchema(data)
.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();