<commit_before>---
title: Building with Components
type: guides
layout: docs
parent_section: guides
order: 2
---

> Fork the [360&deg; Image Gallery Boilerplate on GitHub](https://github.com/aframevr/360-image-gallery-boilerplate).

![360&deg; Image Viewer](/images/docs/360-image-viewer.png)

Let's create an example of building a scene using an
[entity-component-system][ecs] workflow. This guide will introduce three
concepts:

1. Using the standard [components][components] that ship with A-Frame.
2. Using third-party components from the ecosystem.
3. Writing custom components to accomplish whatever we want.

The scene we will build is a **360&deg; image gallery**. There will be three
panels which the user can click on. Once clicked, the background will fade and
swap the 360&deg; images.

<!--toc-->

## Skeleton

This is the starting point for our scene:

```html
<a-scene>
  <a-assets>
    <audio id="click-sound" src="audio/click.ogg"></audio>

    <!-- Images. -->
    <img id="city" src="img/city.jpg">
    <img id="city-thumb" src="img/thumb-city.png">
    <img id="cubes" src="img/cubes.jpg">
    <img id="cubes-thumb" src="img/thumb-cubes.png">
    <img id="sechelt" src="img/sechelt.jpg">
    <img id="sechelt-thumb" src="img/thumb-sechelt.png">
  </a-assets>

  <!-- 360° image. -->
  <a-sky id="image-360" radius="10" src="#city"></a-sky>

  <!-- Link. -->
  <a-plane class="link" height="1" width="1"></a-plane>

  <!-- Camera + Cursor. -->
  <a-camera>
    <a-cursor id="cursor">
      <a-animation begin="click" easing="ease-in" attribute="scale"
                   fill="backwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
      <a-animation begin="fusing" easing="ease-in" attribute="scale"
                   from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
    </a-cursor>
  </a-camera>
</a-scene>
```

We have predefined:

- Several images to choose from in the [Asset Management System][ams] within `<a-assets>`.
- Our 360&deg; image placeholder with [`<a-sky>`][a-sky].
- A [cursor][cursor] with visual feedback using event-driven
[animations][animation-begin], fixed to the [camera][camera].

## Using Standard Components

Standard components are components that ship with A-Frame, like any standard
library. We'll go over how to attach these components to entities and configure
them from HTML.

We want to add an image texture to `<a-plane>` link using the [material
component][material].

The material component is a [multi-property component][multi-property]. To
attach the material component to the plane, we set the component name as an
HTML attribute:

```html
<a-plane class="link" height="1" width="1"
         material></a-plane>
```

Then, we the specify the component data using a syntax that resembles that of
inline CSS styles. We set `shader` to `flat` so the image isn't affected
negatively by lighting. And, we set `src` to `#cubes-thumb`, a selector to one
of the images defined in the [Asset Management System][ams].

```html
<a-plane class="link" height="1" width="1"
         material="shader: flat; src: #cubes-thumb"></a-plane>
```

Let's attach one more standard component, the [sound component][sound]. We want
to make it such that when we click (via gazing) on the link, it plays a click
sound. The syntax is the same as before, but instead we are now using the sound
component's properties. We set `on` to `click` so the sound is played on click.
And, we set `src` to `#click-sound`, a selector to our `<audio>` element.

```html
<a-plane class="link" height="1" width="1"
         material="shader: flat; src: #cubes-thumb"
         sound="on: click; src: #click-sound"></a-plane>
```

Now we have a textured plane that plays a click sound when clicked.

## Using Third-Party Components

We can grab third-party components from the [ecosystem][awesome], drop them into our
scene, and use them in our HTML. Components can do anything. By using components
that other people have developed, we gain tons of power without needing to
write our own code.

We'll go through using three such third-party components: template, layout, and
event-set. First we have to include them. [K-Frame][kframe] is a component
pack by [<NAME>][ngokevin], an A-Frame core developer, that conveniently
includes all three of these components in one bundle.

To drop in K-Frame, download [`k-frame.min.js`](kmin) from the project's
[`dist` folder][kdist] and include it in the `<head>` *after* A-Frame:

```html
<html>
  <head>
    <title>360° Image Browser</title>
    <script src="lib/aframe.min.js"></script>
    <script src="lib/k-frame.min.js"></script>
  </head>
  <body>
    <a-scene>
      <!-- ... -->
    </a-scene><commit_msg>add a comma<commit_after>---
title: Building with Components
type: guides
layout: docs
parent_section: guides
order: 2
---

> Fork the [360&deg; Image Gallery Boilerplate on GitHub](https://github.com/aframevr/360-image-gallery-boilerplate).

![360&deg; Image Viewer](/images/docs/360-image-viewer.png)

Let's create an example of building a scene using an
[entity-component-system][ecs] workflow. This guide will introduce three
concepts:

1. Using the standard [components][components] that ship with A-Frame.
2. Using third-party components from the ecosystem.
3. Writing custom components to accomplish whatever we want.

The scene we will build is a **360&deg; image gallery**. There will be three
panels which the user can click on. Once clicked, the background will fade and
swap the 360&deg; images.

<!--toc-->

## Skeleton

This is the starting point for our scene:

```html
<a-scene>
  <a-assets>
    <audio id="click-sound" src="audio/click.ogg"></audio>

    <!-- Images. -->
    <img id="city" src="img/city.jpg">
    <img id="city-thumb" src="img/thumb-city.png">
    <img id="cubes" src="img/cubes.jpg">
    <img id="cubes-thumb" src="img/thumb-cubes.png">
    <img id="sechelt" src="img/sechelt.jpg">
    <img id="sechelt-thumb" src="img/thumb-sechelt.png">
  </a-assets>

  <!-- 360° image. -->
  <a-sky id="image-360" radius="10" src="#city"></a-sky>

  <!-- Link. -->
  <a-plane class="link" height="1" width="1"></a-plane>

  <!-- Camera + Cursor. -->
  <a-camera>
    <a-cursor id="cursor">
      <a-animation begin="click" easing="ease-in" attribute="scale"
                   fill="backwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
      <a-animation begin="fusing" easing="ease-in" attribute="scale"
                   from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
    </a-cursor>
  </a-camera>
</a-scene>
```

We have predefined:

- Several images to choose from in the [Asset Management System][ams] within `<a-assets>`.
- Our 360&deg; image placeholder with [`<a-sky>`][a-sky].
- A [cursor][cursor] with visual feedback using event-driven
[animations][animation-begin], fixed to the [camera][camera].

## Using Standard Components

Standard components are components that ship with A-Frame, like any standard
library. We'll go over how to attach these components to entities and configure
them from HTML.

We want to add an image texture to `<a-plane>` link using the [material
component][material].

The material component is a [multi-property component][multi-property]. To
attach the material component to the plane, we set the component name as an
HTML attribute:

```html
<a-plane class="link" height="1" width="1"
         material></a-plane>
```

Then, we the specify the component data using a syntax that resembles that of
inline CSS styles. We set `shader` to `flat` so the image isn't affected
negatively by lighting. And, we set `src` to `#cubes-thumb`, a selector to one
of the images defined in the [Asset Management System][ams].

```html
<a-plane class="link" height="1" width="1"
         material="shader: flat; src: #cubes-thumb"></a-plane>
```

Let's attach one more standard component, the [sound component][sound]. We want
to make it such that when we click (via gazing) on the link, it plays a click
sound. The syntax is the same as before, but instead we are now using the sound
component's properties. We set `on` to `click` so the sound is played on click.
And, we set `src` to `#click-sound`, a selector to our `<audio>` element.

```html
<a-plane class="link" height="1" width="1"
         material="shader: flat; src: #cubes-thumb"
         sound="on: click; src: #click-sound"></a-plane>
```

Now we have a textured plane that plays a click sound when clicked.

## Using Third-Party Components

We can grab third-party components from the [ecosystem][awesome], drop them into our
scene, and use them in our HTML. Components can do anything. By using components
that other people have developed, we gain tons of power without needing to
write our own code.

We'll go through using three such third-party components: template, layout, and
event-set. First, we have to include them. [K-Frame][kframe] is a component
pack by [<NAME>][ngokevin], an A-Frame core developer, that conveniently
includes all three of these components in one bundle.

To drop in K-Frame, download [`k-frame.min.js`](kmin) from the project's
[`dist` folder][kdist] and include it in the `<head>` *after* A-Frame:

```html
<html>
  <head>
    <title>360° Image Browser</title>
    <script src="lib/aframe.min.js"></script>
    <script src="lib/k-frame.min.js"></script>
  </head>
  <body>
    <a-scene>
      <!-- ... -->
    </a-scene>
{'fraction_non_alphanumeric': 0.14227858893744005, 'fraction_numerical': 0.014707449642971332, 'mean_word_length': 3.780438104941416, 'pattern_counts': {'":': 0, '<': 111, '<?xml version=': 0, '>': 113, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3210449', 'n_tokens_mistral': 3064, 'n_tokens_neox': 2890, 'n_words': 1115}