aframe
Komponenten
Suche…
Einführung
Im Entity-Component-System-Muster ist eine Komponente ein wiederverwendbarer und modularer Datenblock, den wir in eine Entity einfügen, um Aussehen, Verhalten und / oder Funktionalität hinzuzufügen.
In A-Frame ändern Komponenten Objekte, die 3D-Objekte in der Szene sind. Wir mischen und komponieren Komponenten, um komplexe Objekte zu erstellen. Damit lassen wir three.js und JavaScript-Code in Module einkapseln, die wir deklarativ aus HTML verwenden können. Komponenten sind in etwa analog zu CSS.
Bemerkungen
Methoden zum Definieren von Lebenszyklus-Handlern
Da das Schema die Anatomie ist, sind die Lebenszyklusmethoden die Physiologie. Das Schema definiert die Form der Daten, verwenden die Lifecycle - Handler Methoden , um die Daten , die die Einheit zu modifizieren. Die Handler interagieren normalerweise mit der Entity-API .
Methodenübersicht
Methode | Beschreibung |
---|---|
drin | Wird einmal aufgerufen, wenn die Komponente initialisiert wird. Dient zum Einrichten des Anfangsstatus und zum Instanziieren von Variablen. |
aktualisieren | Wird sowohl bei der Initialisierung der Komponente als auch beim Aktualisieren einer der Eigenschaften der Komponente aufgerufen (z. B. über setAttribute ). Wird verwendet, um die Entität zu ändern. |
Löschen | Wird aufgerufen, wenn die Komponente aus der Entität entfernt wird (z. B. über removeAttribute ) oder wenn die Entität von der Szene getrennt wird. Wird verwendet, um alle vorherigen Änderungen an der Entität rückgängig zu machen. |
Tick | Wird für jede Render-Schleife oder jeden Tick der Szene aufgerufen. Wird für ständige Änderungen oder Prüfungen verwendet. |
abspielen | Wird aufgerufen, wenn die Szene oder das Objekt abgespielt wird, um Hintergrund oder dynamisches Verhalten hinzuzufügen. Wird auch einmal aufgerufen, wenn die Komponente initialisiert wird. Wird verwendet, um das Verhalten zu starten oder wieder aufzunehmen. |
Pause | Wird aufgerufen, wenn die Szene oder das Objekt pausiert, um Hintergrund oder dynamisches Verhalten zu entfernen. Wird auch aufgerufen, wenn die Komponente aus der Entität entfernt wird oder wenn die Entität von der Szene getrennt wird. Wird verwendet, um das Verhalten anzuhalten. |
updateSchema | Wird aufgerufen, wenn eine der Eigenschaften der Komponente aktualisiert wird. Kann verwendet werden, um das Schema dynamisch zu ändern. |
Eigenschaften des Komponentenprototyps
Innerhalb der Methoden haben wir Zugriff auf die Komponente Prototyp über this
:
Eigentum | Beschreibung |
---|---|
diese Daten | Analysierte Komponenteneigenschaften, die aus den Schema-Standardwerten, Mixins und Attributen der Entität berechnet wurden. |
this.el | Referenz auf die Entität [Entität] als HTML-Element. |
this.el.sceneEl | Referenz auf die [Szene] [Szene] als HTML-Element. |
this.id | Wenn die Komponente [mehrere Instanzen] [mehrere] haben kann, die ID der einzelnen Instanz der Komponente (z. B. foo from sound__foo ). |
Methoden
.drin ()
.init ()
wird einmal zu Beginn des Lebenszyklus der Komponente aufgerufen. Eine Entität kann den init
Handler der Komponente aufrufen:
- Wenn die Komponente für die Entität in der HTML-Datei statisch festgelegt ist und die Seite geladen wird.
- Wenn die Komponente über
setAttribute
auf eine verbundene EntitätsetAttribute
. - Wenn die Komponente auf ein nicht verbundenes
appendChild
ist und dasappendChild
dann überappendChild
an die SzeneappendChild
.
Der init
Handler wird häufig verwendet, um:
- Richten Sie den Anfangsstatus und die Variablen ein
- Bindungsmethoden
- Event-Listener anhängen
Beispielsweise würde das init
einer Cursor-Komponente Zustandsvariablen setzen, Methoden binden und Ereignis-Listener hinzufügen:
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 (alteDaten)
.update (oldData)
wird aufgerufen, wenn sich die Eigenschaften der Komponente ändern, auch zu Beginn des Lebenszyklus der Komponente. Eine Entität kann den update
Handler einer Komponente aufrufen:
- Nach dem Aufruf von
init ()
zu Beginn des Komponentenlebenszyklus. - Wenn die Eigenschaften der Komponente mit
.setAttribute
aktualisiert.setAttribute
.
Der update
Handler wird häufig verwendet, um:
-
this.data
Sie die meiste Arbeit aus, indemthis.data
mitthis.data
Änderungen an der Entitätthis.data
. - Ändern Sie die Entität, wenn sich eine oder mehrere Komponenteneigenschaften ändern.
Granulare Änderungen an der Entität können durch [diffing] [diff] des aktuellen Datensatzes ( this.data
) mit dem vorherigen Datensatz vor dem Update ( oldData
) durchgeführt werden.
A-Frame ruft .update()
sowohl zu Beginn des Lebenszyklus einer Komponente als auch bei jeder Änderung der Daten einer Komponente auf (z. B. infolge von setAttribute
). Der Update-Handler verwendet häufig diese this.data
, um die Entität zu ändern. Der Update-Handler hat über sein erstes Argument Zugriff auf den vorherigen Status der Komponentendaten. Anhand der vorherigen Daten einer Komponente können wir genau feststellen, welche Eigenschaften geändert wurden, um granulare Aktualisierungen durchzuführen.
Die update
der sichtbaren Komponente legt beispielsweise die Sichtbarkeit der Entität fest.
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;
}
// ...
});
.Löschen ()
.remove ()
wird aufgerufen, wenn die Komponente von der Entität getrennt wird. Eine Entität kann den remove
Handler einer Komponente aufrufen:
- Wenn die Komponente über
removeAttribute
aus der EntitätremoveAttribute
. - Wenn das
removeChild
von der Szene getrennt wird (z. B.removeChild
).
Der remove
Handler wird häufig verwendet, um:
- Entfernen, rückgängig machen oder bereinigen Sie alle Änderungen der Komponente an der Entität.
- Event-Hörer trennen.
Wenn beispielsweise [Lichtkomponente] [Licht] entfernt wird, entfernt die Lichtkomponente das Lichtobjekt, das zuvor für das Objekt festgelegt wurde, und entfernt es somit aus der Szene.
AFRAME.registerComponent('light', {
// ...
remove: function () {
this.el.removeObject3D('light');
}
// ...
});
.tick (Zeit, ZeitDelta)
.tick ()
wird bei jedem Tick oder Frame der Render-Schleife der Szene aufgerufen. Die Szene ruft den tick
Handler einer Komponente auf:
- In jedem Frame der Render-Schleife.
- In der Größenordnung von 60 bis 120 Mal pro Sekunde.
- Wenn das Objekt oder die Szene nicht angehalten ist (z. B. ist der Inspector geöffnet).
- Wenn das Objekt noch an die Szene angehängt ist.
Der tick
Handler wird häufig verwendet, um:
- Ändern Sie die Entität kontinuierlich in jedem Frame oder in einem Intervall.
- Umfrage nach Bedingungen.
Dem tick
Handler werden die globale Betriebszeit der Szene in Millisekunden ( time
) und der Zeitunterschied in Millisekunden seit dem letzten Frame ( timeDelta
) timeDelta
. Diese können zur Interpolation oder zum Ausführen von Teilen des tick
Handlers in einem festgelegten Intervall verwendet werden.
Die nachverfolgte Steuerungskomponente führt beispielsweise die Animationen des Controllers fort, aktualisiert die Position und Drehung des Controllers und prüft, ob Tasten gedrückt werden.
AFRAME.registerComponent('tracked-controls', {
// ...
tick: function (time, timeDelta) {
this.updateMeshAnimation();
this.updatePose();
this.updateButtons();
}
// ...
});
.Pause ()
.pause ()
wird aufgerufen, wenn das .pause ()
oder die Szene pausiert. Die Entität kann den pause
einer Komponente aufrufen:
- Bevor die Komponente entfernt wird, bevor der
remove
Handler aufgerufen wird. - Wenn die Entität mit
Entity.pause ()
angehalten wird. - Wenn die Szene mit
Scene.pause ()
angehalten wird (z. B. der Inspector wird geöffnet).
Der pause
Handler wird häufig verwendet, um:
- Event-Listener entfernen
- Entfernen Sie alle Chancen für dynamisches Verhalten.
Zum Beispiel wird die Klangkomponente den Ton anhalten und einen Ereignis - Listener entfernen , die einen Ton auf einem Event gespielt hätten:
AFRAME.registerComponent('sound', {
// ...
pause: function () {
this.pauseSound();
this.removeEventListener();
}
// ...
});
.abspielen ()
.play ()
wird aufgerufen, wenn das .play ()
oder die Szene .play ()
wird. Die Entität kann den play
Handler einer Komponente aufrufen:
- Wenn die Komponente zum ersten Mal angeschlossen wird, nachdem der
update
Handler aufgerufen wurde. - Wenn die Entität angehalten wurde, dann aber mit
Entity.play ()
. - Wenn die Szene angehalten wurde, dann aber mit
Scene.play ()
.
Der play
Handler wird häufig verwendet, um:
- Fügen Sie Ereignis-Listener hinzu.
Zum Beispiel gibt die Soundkomponente den Sound wieder und aktualisiert den Event-Listener, der bei einem Event einen Sound abspielen würde:
AFRAME.registerComponent('sound', {
// ...
play: function () {
if (this.data.autoplay) { this.playSound(); }
this.updateEventListener();
}
// ...
});
.updateSchema (Daten)
.updateSchema ()
, falls definiert, bei jeder Aktualisierung aufgerufen, um zu prüfen, ob das Schema dynamisch geändert werden muss.
Der updateSchema
Handler wird häufig verwendet, um:
- Das Schema dynamisch aktualisieren oder erweitern, normalerweise abhängig vom Wert einer Eigenschaft.
Die Geometriekomponente prüft beispielsweise, ob sich die primitive
geändert hat, um festzustellen, ob das Schema für einen anderen Geometrietyp aktualisiert werden soll:
AFRAME.registerComponent('geometry', {
// ...
updateSchema: (newData) {
if (newData.primitive !== this.data.primitive) {
this.extendSchema(GEOMETRIES[newData.primitive].schema);
}
}
// ...
});
KOMPONENTEN-PROTOTYP-VERFAHREN
.flushToDOM ()
Um CPU-Zeit bei der Stringifizierung zu sparen, aktualisiert A-Frame nur im Debug-Modus die serialisierte Darstellung der Komponente im tatsächlichen DOM. Durch Aufrufen von flushToDOM () werden die Daten der Komponente manuell serialisiert und das DOM aktualisiert:
document.querySelector('[geometry]').components.geometry.flushToDOM();
Registrieren Sie eine benutzerdefinierte A-Frame-Komponente
AFRAME.registerComponent (Name, Definition)
Registrieren Sie eine A-Frame-Komponente. Wir müssen Komponenten registrieren, bevor wir sie irgendwo in verwenden . Das heißt, aus einer HTML-Datei sollten Komponenten vorher in Ordnung kommen .
- {string} name - Komponentenname. Die öffentliche API der Komponente, dargestellt durch einen HTML-Attributnamen.
- {Objekt} Definition - Komponentendefinition. Enthält Schema- und Lebenszyklus-Handler-Methoden.
Komponente in foo in Ihrer js-Datei registrieren, z. B. foo-component.js
AFRAME.registerComponent('foo', {
schema: {},
init: function () {},
update: function () {},
tick: function () {},
remove: function () {},
pause: function () {},
play: function () {}
});
Verwendung der FOO- Komponente in Ihrer Szene
<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>
Komponenten-HTML-Formular
Eine Komponente enthält einen Datenbereich in Form einer oder mehrerer Komponenteneigenschaften. Komponenten verwenden diese Daten, um Entitäten zu ändern. Betrachten Sie eine Motorkomponente, können wir Eigenschaften wie Leistung oder Zylinder definieren.
HTML-Attribute stehen für Komponentennamen und der Wert dieser Attribute für Komponentendaten.
Einzelneigenschaftskomponente
Wenn eine Komponente eine Einzeleigenschaftskomponente ist, dh ihre Daten aus einem einzelnen Wert bestehen, sieht der Komponentenwert in HTML wie ein normales HTML-Attribut aus:
<!-- `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>
Multi-Property-Komponente
Wenn eine Komponente eine Komponente mit mehreren Eigenschaften ist, dh die Daten bestehen aus mehreren Eigenschaften und Werten, dann ähnelt der Komponentenwert in HTML den Inline-CSS-Stilen:
<!-- `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>
Definieren eines zugehörigen Schemaobjekts
Das Schema ist ein Objekt, das die Eigenschaft oder die Eigenschaften der Komponente definiert und beschreibt. Die Schlüssel des Schemas sind die Namen der Eigenschaft, und die Werte des Schemas definieren die Typen und Werte der Eigenschaft (im Fall einer Komponente mit mehreren Eigenschaften):
Definieren des Schemas in Ihrer Komponente
AFRAME.registerComponent('bar', {
schema: {
color: {default: '#FFF'},
size: {type: 'int', default: 5}
}
}
Überschreiben definierter Schema-Standardwerte
<a-scene>
<a-entity bar="color: red; size: 20"></a-entity>
</a-scene>
Single-Property-Schema
Eine Komponente kann entweder eine Komponente mit nur einer Eigenschaft (bestehend aus einem anonymen Wert) oder eine Komponente mit mehreren Eigenschaften (bestehend aus mehreren benannten Werten) sein. A-Frame ermittelt anhand der Struktur des Schemas, ob es sich bei einer Komponente um eine Einzeleigenschaft gegenüber einer Mehrfacheigenschaft handelt.
Das Schema einer Komponente mit einer einzigen Eigenschaft enthält type
und / oder default
Die Werte des Schemas sind Werte und keine Objekte:
AFRAME.registerComponent('foo', {
schema: {type: 'int', default: 5}
});
<a-scene>
<a-entity foo="20"></a-entity>
</a-scene>
A-Frame-Eigenschaftstypen für das Komponentenschema
Eigenschaftstypen definieren hauptsächlich, wie das Schema eingehende Daten aus dem DOM für jede Eigenschaft analysiert. Die geparsten Daten stehen dann über die data
Eigenschaft des Prototyps der Komponente zur Verfügung. Nachfolgend finden Sie die integrierten Eigenschaftstypen von A-Frame:
Art der Immobilie | Beschreibung | Standardwert |
---|---|---|
Array | Analysiert durch Kommas getrennte Werte in ein Array (dh "1, 2, 3" to ['1', '2', '3']) . | [] |
Vermögenswert | Für URLs, die auf allgemeine Assets verweisen. Kann URL aus einer Zeichenfolge in Form von url(<url>) analysieren. Wenn der Wert ein Element-ID-Selektor ist (z. B. #texture ), #texture dieser Eigenschaftstyp getElementById und getAttribute('src') auf, um eine URL zurückzugeben. Der asset Eigenschaftstyp kann möglicherweise nicht geändert werden, um XHRs zu verarbeiten oder MediaElements direkt zurückzugeben (z. B. <img> -Elemente). | '' |
Audio- | Gleiche Analyse wie der asset Property-Typ. Wird möglicherweise vom A-Frame Inspector zum Präsentieren von Audio-Assets verwendet. | '' |
boolean | Parses string zu Boolean (dh "false" zu false, alles andere wahr). | falsch |
Farbe | Derzeit wird kein Parsing durchgeführt. Wird hauptsächlich vom A-Frame Inspector verwendet, um einen Farbwähler darzustellen. Außerdem ist es erforderlich, einen Farbtyp zu verwenden, damit Farbanimationen funktionieren. | #F F F |
int | parseInt (z. B. "124.5" bis 124 ). | 0 |
Karte | Gleiche Analyse wie der asset Property-Typ. Wird möglicherweise im A-Frame Inspector zum Präsentieren von Textur-Assets verwendet. | '' |
Modell- | Gleiche Analyse wie der asset Property-Typ. Wird möglicherweise vom A-Frame Inspector zur Präsentation von Modell-Assets verwendet. | '' |
Nummer | parseFloat (z. B. '124.5' bis '124.5' ). | 0 |
Wähler | querySelector (z. B. "#box" an <a-entity id="box"> ). | Null |
SelectorAll | querySelectorAll und konvertiert NodeList in Array (z. B. ".boxes" in [<a-entity class = "Boxen", ...]). | Null |
Schnur | Parsing nicht | '' |
vec2 | Parst zwei Zahlen in ein {x, y} -Objekt (z. B. 1 -2 bis {x: 1, y: -2} . | {x: 0, y: 0} |
vec3 | Analysiert drei Zahlen in ein {x, y, z} -Objekt (z. B. 1 -2 3 bis {x: 1, y: -2, z: 3} . | {x: 0, y: 0, z: 0} |
vec4 | Parst vier Zahlen in ein Objekt {x, y, z, w} (z. B. 1 -2 3 -4.5 bis {x: 1, y: -2, z: 3, w: -4.5} . | {x: 0, y: 0, z: 0, w: 0} |
Das Schema versucht, auf einen Eigenschaftstyp nur bei einem Standardwert zu schließen:
schema: {default: 10} // type: "number"
schema: {default: "foo"} // type: "string"
schema: {default: [1, 2, 3]} // type: "array"
Das Schema legt einen Standardwert fest, wenn es nicht angegeben wird, wenn der Eigenschaftstyp angegeben ist
schema: {type: 'number'} // default: 0
schema: {type: 'string'} // default: ''
schema: {type: 'vec3'} // default: {x: 0, y: 0, z: 0}
Benutzerdefinierter Eigenschaftstyp Wir können auch unseren eigenen Eigenschaftstyp oder Parser definieren, indem Sie anstelle eines type
eine parse
bereitstellen:
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('/');
}
}
}
Zugriff auf Mitglieder und Methoden einer Komponente
Auf die Member und Methoden einer Komponente kann über das Entity-Objekt über die Entität zugegriffen werden. Suchen Sie die Komponente über die Entitätskarte der Komponenten und wir haben Zugriff auf die Komponenten der Komponente. Betrachten Sie diese Beispielkomponente:
AFRAME.registerComponent('foo', {
init: function () {
this.bar = 'baz';
},
qux: function () {
// ...
}
});
Lassen Sie uns auf die Bar- Member- und Qux- Methode zugreifen :
var fooComponent = document.querySelector('[foo]').components.foo;
console.log(fooComponent.bar);
fooComponent.qux();