Ricerca…


introduzione

Nel modello del sistema di entità-componente, un componente è una porzione di dati riutilizzabile e modulare che viene inserita in un'entità per aggiungere aspetto, comportamento e / o funzionalità.

In A-Frame, i componenti modificano le entità che sono oggetti 3D nella scena. Mescoliamo e componiamo i componenti insieme per costruire oggetti complessi. Ci permettono di incapsulare three.js e il codice JavaScript in moduli che possiamo usare in modo dichiarativo da HTML. I componenti sono approssimativamente analoghi ai CSS.

Osservazioni

Metodi di gestione del ciclo di vita delle definizioni

Poiché lo schema è l'anatomia, i metodi del ciclo di vita sono la fisiologia; lo schema definisce la forma dei dati, i metodi del gestore del ciclo di vita utilizzano i dati per modificare l'entità. I gestori di solito interagiscono con l' API Entity .

Panoramica dei metodi

Metodo Descrizione
dentro Chiamato una volta quando il componente è inizializzato. Utilizzato per impostare le variabili iniziali di stato e istanza.
aggiornare Chiamato sia quando il componente è inizializzato e ogni volta che una delle proprietà del componente viene aggiornata (ad esempio, tramite setAttribute ). Utilizzato per modificare l'entità.
rimuovere Chiamato quando il componente viene rimosso dall'entità (ad es. Tramite removeAttribute ) o quando l'entità viene separata dalla scena. Utilizzato per annullare tutte le precedenti modifiche all'entità.
zecca Chiamato su ogni ciclo di rendering o segno di spunta della scena. Utilizzato per modifiche o controlli continui.
giocare Chiamato ogni volta che la scena o l'entità gioca per aggiungere uno sfondo o un comportamento dinamico. Chiamato anche una volta quando il componente è inizializzato. Utilizzato per avviare o riprendere il comportamento.
pausa Chiamato ogni volta che la scena o entità si interrompe per rimuovere qualsiasi sfondo o comportamento dinamico. Chiamato anche quando il componente viene rimosso dall'entità o quando l'entità viene separata dalla scena. Usato per mettere in pausa il comportamento.
updateSchema Chiamato ogni volta che una delle proprietà del componente viene aggiornata. Può essere usato per modificare dinamicamente lo schema.

Proprietà del prototipo del componente

All'interno dei metodi, abbiamo accesso al prototipo del componente tramite this :

Proprietà Descrizione
this.data Proprietà dei componenti analizzati calcolate dai valori predefiniti dello schema, dai mixin e dagli attributi dell'entità.
this.el Riferimento alla [entità] [entità] come elemento HTML.
this.el.sceneEl Riferimento alla [scena] [scena] come elemento HTML.
this.id Se il componente può avere [istanze multiple] [multiple], l'ID della singola istanza del componente (ad es., foo da sound__foo ).

METODI

.dentro ()

.init () viene chiamato una volta all'inizio del ciclo di vita del componente. Un'entità può chiamare il gestore init del componente:

  • Quando il componente è impostato staticamente sull'entità nel file HTML e la pagina viene caricata.
  • Quando il componente è impostato su un'entità collegata tramite setAttribute .
  • Quando il componente è impostato su un'entità non collegata, e l'entità viene quindi allegata alla scena tramite appendChild .

Il gestore di init è spesso usato per:

  • Imposta lo stato iniziale e le variabili
  • Metodi di legatura
  • Allega ascoltatori di eventi

Ad esempio, init di un componente del cursore imposterà variabili di stato, metodi di associazione e aggiungerà listener di eventi:

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) viene chiamato ogni volta che cambiano le proprietà del componente, incluso all'inizio del ciclo di vita del componente. Un'entità può chiamare il gestore di update un componente:

  • Dopo che init () viene chiamato, all'inizio del ciclo di vita del componente.
  • Quando le proprietà del componente vengono aggiornate con .setAttribute .

Il gestore di update è spesso usato per:

  • Fai la maggior parte del lavoro per apportare modifiche all'entità, usando this.data .
  • Modificare l'entità ogni volta che cambiano una o più proprietà del componente.

Le modifiche granulari all'entità possono essere fatte da [diffing] [diff] il dataset corrente ( this.data ) con il dataset precedente prima dell'aggiornamento ( oldData ).

A-Frame chiama .update() sia all'inizio del ciclo di vita di un componente che ogni volta che i dati di un componente cambiano (ad esempio, come risultato di setAttribute ). Il gestore di aggiornamento spesso utilizza this.data per modificare l'entità. Il gestore di aggiornamento ha accesso allo stato precedente dei dati di un componente tramite il suo primo argomento. Possiamo utilizzare i dati precedenti di un componente per indicare esattamente quali proprietà sono state modificate per eseguire aggiornamenti granulari.

Ad esempio, l' update del componente visibile imposta la visibilità dell'entità.

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 () viene chiamato ogni volta che il componente viene staccato dall'entità. Un'entità può chiamare il gestore di remove un componente:

  • Quando il componente viene rimosso dall'entità tramite removeAttribute .
  • Quando l'entità è staccata dalla scena (es. removeChild ).

Il gestore di remove viene spesso utilizzato per:

  • Rimuovi, annulla o ripulisci tutte le modifiche del componente all'entità.
  • Scollega i listener di eventi.

Ad esempio, quando il [componente luce] [luce] viene rimosso, il componente di luce rimuoverà l'oggetto luce che aveva precedentemente impostato sull'entità, rimuovendolo così dalla scena.

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

.tick (time, timeDelta)

.tick () viene chiamato su ogni spunta o fotogramma del ciclo di rendering della scena. La scena chiamerà il gestore di tick un componente:

  • Su ciascun frame del ciclo di rendering.
  • Nell'ordine da 60 a 120 volte al secondo.
  • Se l'entità o la scena non sono in pausa (ad esempio, l'Inspector è aperto).
  • Se l'entità è ancora collegata alla scena.

Il gestore tick è spesso usato per:

  • Modifica continuamente l'entità su ciascun fotogramma o su un intervallo.
  • Sondare per condizioni.

Il gestore tick viene fornito il tempo di attività globale della scena in millisecondi ( time ) e la differenza di tempo in millisecondi dall'ultimo frame ( timeDelta ). Questi possono essere utilizzati per l'interpolazione o per eseguire solo parti del gestore di tick su un intervallo impostato.

Ad esempio, il componente dei controlli tracciati avanza le animazioni del controller, aggiorna la posizione e la rotazione del controller e controlla la pressione dei pulsanti.

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

.pause ()

.pause () viene chiamato quando l'entità o la scena si fermano. L'entità può chiamare il gestore di pause un componente:

  • Prima che il componente venga rimosso, prima che venga chiamato il gestore di remove .
  • Quando l'entità è in pausa con Entity.pause () .
  • Quando la scena è in pausa con Scene.pause () (ad esempio, Inspector è aperto).

Il gestore di pause è spesso usato per:

  • Rimuovi i listener di eventi.
  • Elimina ogni possibilità di comportamento dinamico.

Ad esempio, il componente audio interromperà il suono e rimuoverà un ascoltatore di eventi che avrebbe riprodotto un suono su un evento:

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

.giocare ()

.play () viene chiamato quando l'entità o la scena riprendono. L'entità può chiamare il gestore di play un componente:

  • Quando il componente viene collegato per la prima volta, viene chiamato il gestore di update .
  • Quando l'entità è stata messa in pausa, quindi è stata ripresa con Entity.play () .
  • Quando la scena è stata messa in pausa, quindi è stata ripresa con Scene.play () .

Il gestore di play è spesso utilizzato per:

  • Aggiungi ascoltatori di eventi.

Ad esempio, la componente audio riprodurrà il suono e aggiornerà l'ascoltatore di eventi che riprodurrebbe un suono su un evento:

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

.updateSchema (dati)

.updateSchema () , se definito, viene richiamato su ogni aggiornamento per verificare se lo schema deve essere modificato dinamicamente.

Il gestore di updateSchema è spesso usato per:

  • Aggiorna o estendi dinamicamente lo schema, in genere in base al valore di una proprietà.

Ad esempio, il componente geometry verifica se la proprietà primitive modificata per determinare se aggiornare lo schema per un diverso tipo di geometria:

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

METODI PROTOTIPI COMPONENTI

.flushToDOM ()

Per risparmiare sul tempo della CPU sulla stringa, A-Frame aggiornerà solo in modalità di debug la rappresentazione serializzata del componente nel DOM corrente. La chiamata a flushToDOM () serializzerà manualmente i dati del componente e aggiornerà il DOM:

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

Registra un componente A-Frame personalizzato

AFRAME.registerComponent (nome, definizione)

Registra un componente A-Frame. Dobbiamo registrare i componenti prima di utilizzarli ovunque . Significato da un file HTML, i componenti dovrebbero venire in ordine in precedenza .

  • Nome {string} - Nome del componente. API pubblica del componente rappresentata tramite un nome di attributo HTML.
  • Definizione {Object} - Definizione del componente. Contiene i metodi dello schema e del gestore del ciclo di vita.

Registrazione del componente in foo nel file js, ad es. Foo-component.js

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

Uso del componente foo nella scena

<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>

Modulo HTML componente

Un componente contiene un bucket di dati sotto forma di una o più proprietà del componente. I componenti utilizzano questi dati per modificare le entità. Considerare un componente del motore, potremmo definire proprietà come potenza o cilindri.

Gli attributi HTML rappresentano i nomi dei componenti e il valore di tali attributi rappresenta i dati dei componenti.

Componente di proprietà singola

Se un componente è un componente a proprietà singola, significa che i suoi dati sono costituiti da un singolo valore, quindi in HTML, il valore del componente si presenta come un normale attributo 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>

Componente multiproprietà

Se un componente è un componente multi-proprietà, il che significa che i dati sono costituiti da più proprietà e valori, quindi in HTML, il valore del componente è simile agli stili CSS in linea:

<!-- `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>

Definizione dell'oggetto schema compnente

Lo schema è un oggetto che definisce e descrive la proprietà o le proprietà del componente. Le chiavi dello schema sono i nomi della proprietà e i valori dello schema definiscono i tipi e i valori della proprietà (nel caso di un componente multi-proprietà):

Definizione dello schema nel componente

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

Sovrascrive i valori predefiniti dello schema definiti

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

Schema di una singola proprietà

Un componente può essere un componente a singola proprietà (costituito da un valore anonimo) o un componente a più proprietà (composto da più valori denominati). A-Frame dedurrà se un componente è single-property vs. multi-property in base alla struttura dello schema.

Lo schema di un componente a proprietà singola contiene il type e / o le chiavi default ei valori dello schema sono semplici valori anziché oggetti:

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

Tipi di proprietà dello schema dei componenti di A-Frame

I tipi di proprietà definiscono principalmente come lo schema analizza i dati in entrata dal DOM per ogni proprietà. I dati analizzati saranno quindi disponibili tramite la proprietà data sul prototipo del componente. Di seguito sono riportati i tipi di proprietà incorporati di A-Frame:

Tipo di proprietà Descrizione Valore predefinito
schieramento Analizza i valori separati da virgola in array (cioè, "1, 2, 3" to ['1', '2', '3']) . []
bene Per gli URL che puntano alle risorse generali. Può analizzare l'URL fuori da una stringa sotto forma di url(<url>) . Se il valore è un selettore ID elemento (ad esempio #texture ), questo tipo di proprietà chiamerà getElementById e getAttribute('src') per restituire un URL. Il tipo di proprietà asset può essere modificato o meno per gestire XHR o restituire direttamente MediaElements (ad esempio, <img> elementi). ''
Audio Lo stesso parsing del tipo di proprietà del asset . Sarà probabilmente utilizzato da A-Frame Inspector per presentare risorse audio. ''
booleano Analizza una stringa in booleana (cioè, "false" in false, tutto il resto in verità). falso
colore Attualmente non fa alcuna analisi. Utilizzato principalmente da A-Frame Inspector per presentare un selettore di colori. Inoltre, è necessario utilizzare il tipo di colore per far funzionare le animazioni di colore. #F F F
int Chiama parseInt (ad es. "124.5" su 124 ). 0
carta geografica Lo stesso parsing del tipo di proprietà del asset . Sarà probabilmente usato da A-Frame Inspector per presentare le risorse texture. ''
modello Lo stesso parsing del tipo di proprietà del asset . Sarà probabilmente utilizzato da A-Frame Inspector per presentare le risorse del modello. ''
numero Chiama parseFloat (ad es., '124.5' in '124.5' ). 0
selettore Chiama querySelector (ad esempio, "#box" su <a-entity id="box"> ). nullo
selectorAll Chiama querySelectorAll e converte NodeList in Array (ad esempio, ".boxes" in [<a-entity class = "boxes", ...]), nullo
stringa Non fa alcuna analisi. ''
vec2 Analizza due numeri in un oggetto {x, y} (ad esempio, da 1 -2 a {x: 1, y: -2} . {x: 0, y: 0}
vec3 Analizza tre numeri in un oggetto {x, y, z} (ad es. 1 -2 3 in {x: 1, y: -2, z: 3} . {x: 0, y: 0, z: 0}
vec4 Analizza quattro numeri in un oggetto {x, y, z, w} (ad es. 1 -2 3 -4.5 a {x: 1, y: -2, z: 3, w: -4.5} . {x: 0, y: 0, z: 0, w: 0}
Tipo di proprietà Inferenza

Lo schema proverà ad inferire un tipo di proprietà dato solo un valore predefinito:

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

Lo schema imposterà un valore predefinito se non fornito, dato il tipo di proprietà:

schema: {type: 'number'}  // default: 0
schema: {type: 'string'}  // default: ''
schema: {type: 'vec3'}  // default: {x: 0, y: 0, z: 0}
Tipo di proprietà personalizzata

Possiamo anche definire il nostro tipo di proprietà o parser fornendo una funzione di parse al posto di un type :

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('/');
    }
  }
}

Accesso ai membri e ai metodi di un componente

È possibile accedere ai membri e ai metodi di un componente tramite l'entità dall'oggetto .components . Cerca il componente dalla mappa di componenti dell'entità e avremo accesso agli interni del componente. Considera questo componente di esempio:

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

Accediamo al membro della barra e al metodo 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow