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ät setAttribute .
  • Wenn die Komponente auf ein nicht verbundenes appendChild ist und das appendChild dann über appendChild an die Szene appendChild .

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, indem this.data mit this.data Änderungen an der Entität this.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ät removeAttribute .
  • 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}
Eigenschaftstyp Inferenz

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();


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow