npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aframe-react-assets

v2.0.5

Published

A React component for smart managing your AFrame VR assets. You can declare your assets at your React component.

Downloads

19

Readme

npm npm

Introduce

A React component for smart managing your AFrame VR assets. You can declare your assets at your React component.

If you need an example of Aframe with React, I've made a real demo for Aframe, include implementation of this package. Just take a look at https://github.com/luatnd/aframe-react-demo

The problem why you need to use this package

TL;DR

Aframe assets manager system require you too put all your assets inside only one <a-assets> tag in your app AND a must be the direct child of <a-scene>. But when you break your very big layout into so many nested React components, you need to find a way to put your assets at your components to ensure component oriented spirit of React while stay out of being conflict with Aframe assets manager system. Using aframe-react-assets is a good solution for you.

You can skip the detail and jump to How section if you aren't interested in the detail of problem.

Another benefit is you can track the progress of assets loading if you want, see onLoadingByAmount() event handle:

aframe-react-assets loading preview

Detail of the problem

This is a good HTML section for Aframe, we'll take about migrating the Sky section and its relate assets in to React component:

<a-scene>
     <!-- Aframe Asset management system. -->
    <a-assets>
    
        <!-- <Sky/> React component's assets: -->
        <img id="sky" src="assets/img/sky.jpg" alt="Sky Component's asset #sky"/>
        <video id="videoMilkyWay" src="assets/img/videoMilkyWay.mp4"/>

        <!-- Other Component Assets -->
        <a-asset-item id="horse-obj" src="horse.obj"></a-asset-item>
        <a-asset-item id="horse-mtl" src="horse.mtl"></a-asset-item>
        <a-mixin id="giant" scale="5 5 5"></a-mixin>
        <audio id="neigh" src="neigh.mp3"></audio>
        <img id="advertisement" src="ad.png">
        <video id="kentucky-derby" src="derby.mp4"></video>
    </a-assets>

    <a-entity class="camera" camera=""></a-entity>
    
    <Entity>
    
        <!-- This will be <Sky/> Component -->
        <Entity className="theSky">
            <a-sky className="sky" src="#sky" rotation="0 0 0"/>
            <!-- ... more content ... -->
            <!-- ... more content ... -->
            <!-- ... more content ... -->
        </Entity>
        <!--End Sky component-->


        <Light/>
        <FloorAndWall/>
        
        <Entity className="advertise">
            <a-plane src="#advertisement"></a-plane>
            <a-sound src="#neigh"></a-sound>
            <a-entity geometry="primitive: plane" material="src: #kentucky-derby"></a-entity>
            <a-entity mixin="giant" obj-model="obj: #horse-obj; mtl: #horse-mtl"></a-entity>
        </Entity>

    </Entity>
</a-scene>

So if you create Aframe with React, you need to divide your Aframe HTML into some small component.

<Entity className="theSky">
    <a-sky className="sky" src="#sky" rotation="0 0 0"/>
    <!-- ... more content ... -->
    <!-- ... more content ... -->
    <!-- ... more content ... -->
</Entity>

into this:

<Sky/>

So what about the Sky assets ?

<img id="sky" src="assets/img/sky.jpg" alt="Sky Component's asset #sky"/>
<video id="videoMilkyWay" src="assets/img/videoMilkyWay.mp4"/>

AFrame recommend you to put your assets "inside" the (You might read the TL;DR section again)

You can not do like this:

Sky.jsx:

<Entity className="theSky">
    {/* Aframe do not recommend you put your assets here: */}
    <img id="sky" src="assets/img/sky.jpg" alt="Sky Component's asset #sky"/>
    <video id="videoMilkyWay" src="assets/img/videoMilkyWay.mp4"/>

    <a-sky className="sky" src="#sky" rotation="0 0 0"/>
    <!-- ... more content ... -->
    <!-- ... more content ... -->
    <!-- ... more content ... -->
</Entity>

Because:

  1. AFrame assets manager system rules, Read the TL;DR
  2. If your react component was re-render, browser will re-make a new request to load assets again. This is redundant. Imagine your component contain 10 assets, and component will be re-render every second. How bad that will be ?
  3. Use Aframe asset manager system is a most efficient way to use your assets

How

How to use this plugin

0.. Install plugin

yarn add aframe-react-assets

1.. Declare your static Assets array at your component:

import imgSky from "assets/img/sky.jpg";
import videoMilkyWay from "assets/img/videoMilkyWay.mp4";

export default class Sky extends React.Component {
  static Assets = [
    <img id="sky" src={imgSky} alt="sky"/>,
    <video id="videoMilkyWay" src={videoMilkyWay}/>
  ];
  
  render() {
    return (
      <Entity {...this.props}>
        <a-sky className="sky" src="#sky" rotation="0 0 0"/>
      </Entity>
    );
  }
}

2.. Create an rootAssets.js like this:

rootAssets.js

export default {
  // [ComponentName:string]: Your declared Assets array
  Sky:          require('../Sky/Sky').default.Assets,
  FloorAndWall: require('../FloorAndWall/FloorAndWall').default.Assets,
  Workspace:    require('../Workspace/Workspace').default.Assets,
  BackWall:     require('../Decorator/BackWall').default.Assets,
  FrontSea:     require('../Decorator/FrontSea').default.Assets,
  Center:       require('../Decorator/Center').default.Assets,
  Light:        require('../Light/Light').default.Assets,
};

3.. Use Assets:

MyScene.jsx:

import {Entity, Scene} from 'aframe-react';
import Assets from 'aframe-react-assets';
import rootAssets from 'path/to/rootAssets.js';

export default class MyScene extends React.Component {
  render () {
    return <Scene>
      {/* Use assets here */}
      <Assets 
        assets={rootAssets}
        timeout={4e4}
        interval={200}
        debug={true}
        onLoad={this.updateAssetsLoadingStatus}
        onLoadingBySize={this.updateAssetsCurrentInfo}
        onLoadingByAmount={this.updateAssetsLoadingInfo}
      />
             
      <Entity camera="userHeight: 2; fov: 80;"/>
      <Entity>
         <Sky/>
         <Light/>  
         <FloorAndWall/>
         <Workspace/>

         <Entity className="decorator">
           <BackWall/>
           <FrontSea/>
           <Center/>
         </Entity>
         
       </Entity>
     </Scene>
  }
}

Assets Props

assets: object
  • See rootAssets.js above
timeout: number
  • Stop loading pending/waiting assets and consider the loading was all successful when this value was reached, in milliseconds.
  • @default 30000
interval: number
  • The interval duration in milliseconds that this component will do update via event handle on*() bellow
  • Example: onLoadingByAmount() will be triggered each 200ms (default)
  • @default 200
debug: boolean
  • Turn on console.log this component activities
onLoad(status: boolean): void
  • When <a-assets/> was start loading its assets: onLoad(true) was triggered.
  • When all assets was loaded or exceed timeout props: onLoad(false) was triggered.
onLoadingBySize({assetCurrentLoadedBytes: number, assetTotalBytes: number}): void
  • onLoadingBySize was triggered each interval milliseconds. See interval props.
  • You can calculate current progress by percent: const currentPercent = assetCurrentLoadedBytes / assetTotalBytes * 100;
  • NOTE: TODO: This feature has not completed yet;
  • NOTE: Choose and use only one onLoading*() handle, because they're using same interval manager
onLoadingByAmount({assetLoaded: number, assetTotal: number, assetCurrentItem: object}):void
  • onLoadingByAmount was triggered each interval milliseconds. See interval props.
  • Update loading info every interval milliseconds
    • assetLoaded: Number of successfully loaded assets,
    • assetTotal: Total amount of all your assets,
    • assetCurrentItem: The current loaded assets, value is the html element
  • NOTE: Choose and use only one onLoading*() handle, because they're using same interval manager

Contribution

You're very welcome. This package is an just quick initial idea, for a production app, this plugin is lacking:

  • Track how many bytes assets was loaded (there was a draft version inside this package)
  • Code splitting support (It's might buggy when this component re-render)