Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rozek/aframe-within-svelte

some notes on how to use A-Frame within a Svelte Application
https://github.com/rozek/aframe-within-svelte

a-frame svelte svelte3

Last synced: 12 days ago
JSON representation

some notes on how to use A-Frame within a Svelte Application

Awesome Lists containing this project

README

        

# aframe-within-svelte #

some notes on how to use A-Frame within a Svelte Application

[A-Frame](https://github.com/aframevr/aframe) is a framework for creating "virtual reality experiences" in the same way as "ordinary" web pages: by means of HTML elements with attributes and content. Under the hood, A-Frame uses the DOM only to manage the hierarchical description of a VR/AR "scene" and its "assets" (especially, without burdening the browser's layout engine) and then simply maps these elements to corresponding objects of the underlying [Three.js](https://github.com/mrdoob/three.js/) library (this approach drastically simplifies the use of Three.js)

[Svelte](https://github.com/sveltejs/svelte) is a tool for building web applications from components which look and behave like custom HTML elements. Svelte accesses the DOM directly to manage these elements and update their attributes and contents upon changes.

While the underlying execution models of A-Frame and Svelte differ completely, their use of the DOM as a common data base ensures a fairly smooth interaction.

This repository illustrates how to integrate A-Frame entities, components and systems into a Svelte application - and how to use Svelte to implement custom A-Frame entities, components and systems. As you will see, it's quite simple.

### Terminology ###

A-Frame has an [entity-component-system](https://aframe.io/docs/1.3.0/introduction/entity-component-system.html) (ECS) architecture. As a consequence, an A-Frame "component" is something completely different than a Svelte "component". The following table tries to give a (really) rough mapping between A-Frame "Entities", "Components" and "Systems" and their Svelte counterparts:

A-FrameSvelte
Entitysimilar to a Svelte Component
Componentsimilar to Svelte "props"
Systemthe business logic behind these "props"

In an object-oriented world, ECS "components" contain the data of a mixin or (in case of multiple inheritance) a single superclass, whereas a "system" contains the mixin's or superclass's implementation. ECS "entities" then simply represent instances of (classes inheriting from) these mixins or superclasses without any own data or business logic.

### Example ###

This repository contains files for an example which demonstrates all mechanisms described below:

* [`aframe-component.js`](./aframe-component.js) - implements an A-Frame "component"
* [`aframe-system.js`](./aframe-system.js) - implements an A-Frame "system" (and its associated "component")
* [`aframe-primitive.js`](./aframe-primitive.js) - implements an A-Frame "primitive"
* [`AFrameEntity.svelte`](./AFrameEntity.svelte) - implements a Svelte component which acts like an A-Frame "entity"
* [`App.svelte`](./App.svelte) - contains the Svelte application which uses all modules shown above

`aframe-component.js` and `aframe-system.js` log invocations of their lifecycle method on the browser console - thus, make sure to open the browser's developer tools and watch the console.

### Svelte REPL ###

While the example also exists in the [Svelte REPL](https://svelte.dev/repl/43f54b1b2ab34533a69c363067194d2d), the mechanisms behind this REPL currently seem to be incompatible with A-Frame - the example therefore refuses to start.

Just build the example offline instead and run it locally on your own computer.

## Using A-Frame in a Svelte Application ##

Assuming that you are following the usual workflow for Svelte applications (which finally runs [Rollup](https://rollupjs.org/guide/en/) or [WebPack](https://webpack.js.org/) to bundle a set of modules into an optimized JavaScript distribution), everything starts by installing A-Frame as such a module:

```bash
npm install --save aframe
```

Within a Svelte file, you then just import A-Frame like so:

```html

import "aframe"

```

Two remarks seem appropriate:

* importing A-Frame will blow up your final JavaScript distribution file by more than 2 MB - that's ok since A-Frame is not "tree-shakeable" yet and there seem to be [no plans to make it tree-shakeable](https://github.com/aframevr/aframe/issues/4242) in the near future
* since A-Frame actually expects to be included by a `` element in the `<head>` section of an HTML document, it issues a _warning_ in the browser console if this is not the case - just ignore this warning...

After having imported A-Frame, its elements may be used like any other HTML element in a Svelte application:

```html
<a-scene>
<a-sky color="#ECECEC"/>
<a-box color="#4CC3D9"
position="0 0.5 -3" rotation="0 45 0"/>
<a-plane width="4" height="4" color="#7BC8A4"
position="0 0 -4" rotation="-90 0 0"/>
</a-scene>
```

Even better: Svelte's reactivity mechanisms work as usual:

```html
<script>
let BoxIsVisible = false
setTimeout(() => { BoxIsVisible = true }, 5000)

let Angle = 45
setInterval(() => { Angle++ }, 100)


{#if BoxIsVisible}

{/if}

```

Note: while the rotation animation shown above works (and illustrates that you don't have to synchronize your business logic with the 3D rendering loop) using A-Frame's `animation` component should be preferred.

## Implementing an A-Frame Component within Svelte ##

A-Frame provides a mechanism for [adding new "components"](https://aframe.io/docs/1.3.0/introduction/writing-a-component.html) - this mechanism still works within a Svelte application.

Just [implement the new A-Frame component](https://aframe.io/docs/1.3.0/core/component.html) in a separate JavaScript (or TypeScript) file:

```javascript
import "aframe"

AFRAME.registerComponent('a-svelte-component',{
... // add your specification and implementation here
})
```

and import it into your Svelte application. From then on it may be added to A-Frame elements as usual:

```html

import "aframe"
import "./aframe-component.js"

```

## Implementing an A-Frame System within Svelte ##

A-Frame also provides a mechanism for adding new "systems" - and, again, this mechanism also works within a Svelte application.

Just [implement the new A-Frame system]([https://aframe.io/docs/1.3.0/core/component.html](https://aframe.io/docs/1.3.0/core/systems.html)) in a separate JavaScript (or TypeScript) file:

```javascript
import "aframe"

AFRAME.registerSystem('a-svelte-system',{
... // add your specification and implementation here
})

AFRAME.registerComponent('a-svelte-system',{
... // add your specification and implementation here
})
```

and import it into your Svelte application. From then on it may be added to A-Frame as usual:

```html

import "aframe"
import "./aframe-system.js"

```

## Implementing an A-Frame Primitive within Svelte ##

You may even [implement new A-Frame "primitives"](https://aframe.io/docs/1.3.0/introduction/html-and-primitives.html) within Svelte.

As before, implement the primitive in a separate JavaScript (or TypeScript) file:

```javascript
import "aframe"

AFRAME.registerPrimitive('a-svelte-primitive',{
defaultComponents: { /* ... */ },
mappings: { /* ... */ }
})
```

and import it into your Svelte application where it may be used like any other A-Frame tag:

```html

import "aframe"
import "./aframe-primitive.js"

```

## Using a Svelte Component as an A-Frame Entity ##

Svelte may also be used to implement new A-Frame entities in order to benefit from Svelte features like [stores](https://svelte.dev/tutorial/writable-stores), [actions](https://svelte.dev/tutorial/actions), [contexts](https://svelte.dev/tutorial/context-api) and [component composition](https://svelte.dev/tutorial/slots).

Just implement an ordinary Svelte component in a separate `.svelte` file and import A-Frame as usual:

```html

import "aframe"

export let color = 'red'

```

Within the Svelte application you may then import and use the Svelte component as usual:

```html

import "aframe"
import AFrameEntity from './AFrameEntity.svelte'

let color = 'blue'

```

## License ##

[MIT License](LICENSE.md)