Buscar..


Introducción

En el patrón entidad-componente-sistema, un componente es una porción de datos reutilizable y modular que conectamos en una entidad para agregar apariencia, comportamiento y / o funcionalidad.

En A-Frame, los componentes modifican las entidades que son objetos 3D en la escena. Mezclamos y componemos componentes para construir objetos complejos. Nos permiten encapsular el código three.js y JavaScript en módulos que podemos usar declarativamente desde HTML. Los componentes son aproximadamente análogos a CSS.

Observaciones

Definición de los métodos de manejo del ciclo de vida

Con el esquema siendo la anatomía, los métodos del ciclo de vida son la fisiología; el esquema define la forma de los datos, los métodos del manejador del ciclo de vida usan los datos para modificar la entidad. Los manejadores generalmente interactuarán con la API de la entidad .

Resumen de los métodos

Método Descripción
en eso Se llama una vez cuando se inicializa el componente. Se utiliza para configurar el estado inicial y crear instancias de las variables.
actualizar Se llama tanto cuando el componente se inicializa y cada vez que se actualiza alguna de las propiedades del componente (por ejemplo, a través de setAttribute ). Se utiliza para modificar la entidad.
retirar Se llama cuando el componente se elimina de la entidad (por ejemplo, a través de removeAttribute ) o cuando la entidad se separa de la escena. Se utiliza para deshacer todas las modificaciones anteriores a la entidad.
garrapata Llamado en cada bucle de render o tick de la escena. Se utiliza para cambios continuos o cheques.
jugar Se llama cada vez que se reproduce la escena o entidad para agregar cualquier fondo o comportamiento dinámico. También se llama una vez cuando se inicializa el componente. Se utiliza para iniciar o reanudar el comportamiento.
pausa Se llama cuando la escena o entidad se detiene para eliminar cualquier fondo o comportamiento dinámico. También se llama cuando el componente se elimina de la entidad o cuando la entidad se separa de la escena. Se utiliza para pausar el comportamiento.
updateSchema Se llama cada vez que se actualiza alguna de las propiedades del componente. Se puede utilizar para modificar dinámicamente el esquema.

Propiedades de prototipo de componente

Dentro de los métodos, tenemos acceso al prototipo del componente a través de this :

Propiedad Descripción
este.data Las propiedades del componente analizadas se calculan a partir de los valores predeterminados del esquema, los mixins y los atributos de la entidad.
esto.el Referencia a la [entidad] [entidad] como un elemento HTML.
esto.el.sceneEl Referencia a la [escena] [escena] como un elemento HTML.
esto.id Si el componente puede tener [varias instancias] [múltiples], el ID de la instancia individual del componente (por ejemplo, foo from sound__foo ).

Metodos

.en eso ()

.init () se llama una vez al principio del ciclo de vida del componente. Una entidad puede llamar al controlador de init del componente:

  • Cuando el componente se establece estáticamente en la entidad en el archivo HTML y la página se carga.
  • Cuando el componente se establece en una entidad adjunta a través de setAttribute .
  • Cuando el componente se establece en una entidad no adjunta, y la entidad se adjunta a la escena a través de appendChild .

El controlador de init se suele utilizar para:

  • Configurar el estado inicial y las variables.
  • Métodos de unión
  • Adjuntar oyentes de eventos

Por ejemplo, la init un componente del cursor establecería variables de estado, métodos de enlace y agregaría escuchas de eventos:

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) cada vez que cambian las propiedades del componente, incluso al comienzo del ciclo de vida del componente. Una entidad puede llamar al controlador de update un componente:

  • Después de llamar a init () , al comienzo del ciclo de vida del componente.
  • Cuando las propiedades del componente se actualizan con .setAttribute .

El controlador de update se utiliza a menudo para:

  • Haga la mayor parte del trabajo para hacer modificaciones a la entidad, utilizando this.data .
  • Modifique la entidad siempre que cambien una o más propiedades del componente.

Las modificaciones granulares de la entidad pueden realizarse [difingir] [dif] el conjunto de datos actual ( this.data ) con el conjunto de datos anterior antes de la actualización ( oldData ).

A-Frame llama a .update() tanto al principio del ciclo de vida de un componente como cada vez que los datos de un componente cambian (por ejemplo, como resultado de setAttribute ). El controlador de actualización a menudo utiliza this.data para modificar la entidad. El controlador de actualización tiene acceso al estado anterior de los datos de un componente a través de su primer argumento. Podemos usar los datos anteriores de un componente para indicar exactamente qué propiedades se modificaron para hacer actualizaciones granulares.

Por ejemplo, la update del componente visible establece la visibilidad de la entidad.

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

.retirar ()

.remove () se llama cuando el componente se separa de la entidad. Una entidad puede llamar al controlador de remove un componente:

  • Cuando el componente se elimina de la entidad a través de removeAttribute .
  • Cuando la entidad se separa de la escena (por ejemplo, removeChild ).

El controlador de remove se utiliza a menudo para:

  • Eliminar, deshacer o limpiar todas las modificaciones del componente a la entidad.
  • Separar a los oyentes del evento.

Por ejemplo, cuando se elimina el [componente de luz] [luz], el componente de luz eliminará el objeto de luz que había colocado previamente en la entidad, eliminándolo así de la escena.

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

.tick (time, timeDelta)

Se llama a .tick () en cada tic o trama del bucle de renderizado de la escena. La escena llamará al manejador de tick un componente:

  • En cada cuadro del bucle de render.
  • Del orden de 60 a 120 veces por segundo.
  • Si la entidad o escena no está en pausa (por ejemplo, el Inspector está abierto).
  • Si la entidad todavía está vinculada a la escena.

El controlador de tick se utiliza a menudo para:

  • Modificar continuamente la entidad en cada marco o en un intervalo.
  • Encuesta de condiciones.

El controlador de tick se proporciona el tiempo de actividad global de la escena en milisegundos ( time ) y la diferencia de tiempo en milisegundos desde el último fotograma ( timeDelta ). Se pueden usar para interpolación o solo para ejecutar partes del controlador de tick en un intervalo establecido.

Por ejemplo, el componente de controles rastreados progresará las animaciones del controlador, actualizará la posición y la rotación del controlador y verificará si se presionan los botones.

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

.pause ()

.pause () cuando la entidad o escena se detiene. La entidad puede llamar al controlador de pause un componente:

  • Antes de eliminar el componente, antes de llamar al controlador de remove .
  • Cuando la entidad está en pausa con Entity.pause () .
  • Cuando la escena está en pausa con Scene.pause () (por ejemplo, se abre el Inspector).

El controlador de pause se utiliza a menudo para:

  • Eliminar oyentes de eventos.
  • Eliminar cualquier posibilidad de comportamiento dinámico.

Por ejemplo, el componente de sonido pausará el sonido y eliminará un detector de eventos que haya reproducido un sonido en un evento:

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

.jugar ()

.play () cuando se reanuda la entidad o la escena. La entidad puede llamar al controlador de play un componente:

  • Cuando el componente se adjunta por primera vez, después de llamar al controlador de update .
  • Cuando la entidad se detuvo, pero luego se reanudó con Entity.play () .
  • Cuando la escena se detuvo, pero luego se reanudó con Scene.play () .

El controlador de play suele utilizarse para:

  • Añadir oyentes de eventos.

Por ejemplo, el componente de sonido reproducirá el sonido y actualizará el detector de eventos que reproducirá un sonido en un evento:

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

.updateSchema (datos)

.updateSchema () , si está definido, se llama en cada actualización para verificar si el esquema necesita ser modificado dinámicamente.

El controlador updateSchema se usa a menudo para:

  • Actualice o extienda dinámicamente el esquema, generalmente dependiendo del valor de una propiedad.

Por ejemplo, el componente de geometría verifica si la propiedad primitive cambió para determinar si actualizar el esquema para un tipo diferente de geometría:

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

MÉTODOS DE PROTOTIPO DE COMPONENTES

.flushToDOM ()

Para ahorrar tiempo de CPU en la cadena de caracteres, A-Frame solo actualizará en modo de depuración la representación serializada del componente en el DOM real. Al llamar a flushToDOM () se serializarán manualmente los datos del componente y se actualizará el DOM:

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

Registrar un componente A-Frame personalizado

AFRAME.registerComponent (nombre, definición)

Registrar un componente A-Frame. Debemos registrar los componentes antes de usarlos en cualquier parte. . Significado de un archivo HTML, los componentes deben venir en orden antes .

  • {string} name - Nombre del componente. La API pública del componente como se representa a través de un nombre de atributo HTML.
  • Definición de {objeto} - Definición de componente. Contiene esquemas y métodos de manejo del ciclo de vida.

Registrar componente en foo en su archivo js, ​​por ejemplo, foo-component.js

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

Uso del componente foo en tu escena.

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

Componente HTML Formulario

Un componente contiene un grupo de datos en forma de una o más propiedades del componente. Los componentes utilizan estos datos para modificar entidades. Considere un componente del motor, podríamos definir propiedades tales como caballos de fuerza o cilindros.

Los atributos HTML representan nombres de componentes y el valor de esos atributos representa datos de componentes.

Componente de propiedad única

Si un componente es un componente de una sola propiedad, lo que significa que sus datos consisten en un solo valor, en HTML, el valor del componente parece un atributo HTML normal:

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

Si un componente es un componente de múltiples propiedades, lo que significa que los datos se componen de múltiples propiedades y valores, entonces en HTML, el valor del componente se parece a los estilos de CSS en línea:

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

Definición de objeto de esquema compnent

El esquema es un objeto que define y describe la propiedad o propiedades del componente. Las claves del esquema son los nombres de la propiedad, y los valores del esquema definen los tipos y valores de la propiedad (en el caso de un componente de múltiples propiedades):

Definiendo esquema en tu componente

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

Anular los valores predeterminados del esquema definido

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

Esquema de propiedad única

Un componente puede ser un componente de una sola propiedad (que consiste en un valor anónimo) o un componente de múltiples propiedades (que consta de múltiples valores con nombre). A-Frame deducirá si un componente es de una sola propiedad o de múltiples propiedades en función de la estructura del esquema.

El esquema de un componente de una sola propiedad contiene claves de type y / o default , y los valores del esquema son valores simples en lugar de objetos:

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

Tipos de propiedad del esquema de componentes de A-Frame

Los tipos de propiedad definen principalmente cómo el esquema analiza los datos entrantes del DOM para cada propiedad. Los datos analizados estarán disponibles a través de la propiedad de data en el prototipo del componente. A continuación se muestran los tipos de propiedad incorporados de A-Frame:

tipo de propiedad Descripción Valor por defecto
formación Analiza los valores separados por comas en la matriz (es decir, "1, 2, 3" to ['1', '2', '3']) . []
activo Para direcciones URL que apuntan a activos generales. Puede analizar la URL de una cadena en forma de url(<url>) . Si el valor es un selector de ID de elemento (por ejemplo, #texture ), este tipo de propiedad llamará a getElementById y getAttribute('src') para devolver una URL. El tipo de propiedad del asset puede o no cambiar para manejar XHR o devolver MediaElements directamente (por ejemplo, <img> elementos). ''
audio El mismo análisis que el tipo de propiedad del asset . Posiblemente será utilizado por el inspector de fotogramas A para presentar activos de audio. ''
booleano Analiza la cadena a booleano (es decir, "false" a falso, todo lo demás es verdadero). falso
color Actualmente no hace ningún análisis. Utilizado principalmente por el inspector de fotograma A para presentar un selector de color. Además, es necesario utilizar el tipo de color para que funcionen las animaciones en color. #FFF
En t Llama a parseInt (por ejemplo, "124.5" a 124 ). 0
mapa El mismo análisis que el tipo de propiedad del asset . Posiblemente se utilizará por el inspector de fotograma A para presentar activos de textura. ''
modelo El mismo análisis que el tipo de propiedad del asset . Posiblemente se usará por el inspector de fotograma A para presentar los activos del modelo. ''
número Llama a parseFloat (por ejemplo, '124.5' a '124.5' ). 0
selector Llama a querySelector (por ejemplo, "#box" a <a-entity id="box"> ). nulo
selectorTodo Llama a querySelectorAll y convierte NodeList a Array (por ejemplo, ".boxes" a [<a-entity class = "boxes", ...]), nulo
cuerda No hace ningún análisis. ''
vec2 Analiza dos números en un objeto {x, y} (por ejemplo, 1 -2 a {x: 1, y: -2} . {x: 0, y: 0}
vec3 Analiza tres números en un objeto {x, y, z} (por ejemplo, 1 -2 3 a {x: 1, y: -2, z: 3} . {x: 0, y: 0, z: 0}
vec4 Analiza cuatro números en un objeto {x, y, z, w} (p. Ej., 1 -2 3 -4.5 a {x: 1, y: -2, z: 3, w: -4.5} . {x: 0, y: 0, z: 0, w: 0}
Tipo de propiedad Inferencia

El esquema intentará inferir un tipo de propiedad dado solo un valor predeterminado:

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

El esquema establecerá un valor predeterminado si no se proporciona, dado el tipo de propiedad:

schema: {type: 'number'}  // default: 0
schema: {type: 'string'}  // default: ''
schema: {type: 'vec3'}  // default: {x: 0, y: 0, z: 0}
Tipo de propiedad personalizada

También podemos definir nuestro propio tipo de propiedad o analizador proporcionando una función de parse en lugar de 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('/');
    }
  }
}

Acceso a los miembros y métodos de un componente

Se puede acceder a los miembros y métodos de un componente a través de la entidad desde el objeto .components . Busque el componente en el mapa de componentes de la entidad y tendremos acceso a los componentes internos del componente. Considere este componente de ejemplo:

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

Vamos a acceder al miembro de la barra y al método 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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow