Skip to content

An A-frame component that allows you to add multiple material sources

Notifications You must be signed in to change notification settings

elbobo/aframe-multisrc-component

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A-frame multisrc component

An A-frame component that allows you to add separate image/video textures to different sides of standard a-frame shapes.

Updates

New in version 0.2 -> Want to only have an image on the front and top of your cube? Now you can. Target specific sides with textures declaratively.

Version 0.3 - Video playback bug fixed

Multisrc component animated demo

The multisrc component integrates with all existing components allowing you to define a different texture for each side of an shape while still controlling all other material properties with the standard material attributes (color, opacity etc.). It should work seamlessly with all other aframe components too (physics, animation etc. Please let me know of any issues).

Basics

As with the standard src attribute you can use multisrc with images/videos that have been preloaded in the assets tag (recommended for all the reasons described here). There are a few different ways to assign your textures with multisrc. Please see below

  <head>
    <script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
    <script src="https://cdn.rawgit.com/elbobo/aframe-multisrc-component/b6d23310/dist/0.3/aframe-multisrc-component.js"></script>
  </head>
  <body>
    <a-scene>

      <a-assets>
        <img id="right" src="path/to/rightimage.png">
        <img id="left" src="path/to/leftimage.png">
        <img id="top" src="path/to/topimage.png">
        <img id="bottom" src="path/to/bottomimage.png">
        <img id="front" src="path/to/frontimage.png">
        <img id="back" src="path/to/backimage.png">
      </a-assets>
      
      <!-- METHOD 1 -->
      
      <!-- If you know you want to assign assets to ALL sides, using the `srcs` attribute is probably easiest -->
      
      <!-- you can assign the images as ids from assets -->

      <a-box 
        position="0 1.5 -2" 
        multisrc="srcs:#right,#left,#top,#bottom,#front,#back"
        color="blue"
        opacity="0.5"
        shadow>
      </a-box>
      
      <!-- OR add the images/videos inline -->
      
      <a-box 
        position="0 1.5 -2" 
        multisrc="srcs:path/to/rightimage.png,path/to/leftimage.png,path/to/topimage.png,path/to/bottomimage.png,path/to/frontimage.png,path/to/backimage.png"
        color="blue"
        opacity="0.5"
        shadow>
      </a-box>
      
  <!-- OR When defining assets inline, avoid rewriting lengthy paths (if assets in the same folder) using `srcspath` -->
  <!-- Use the `srcspath` attribute and then simply list the image/video names like so -->
      
      <a-box 
       position="0 1.5 -2" 
       multisrc="srcspath:path/to/;srcs:rightimage.png,leftimage.png,topimage.png,bottomimage.png,frontimage.png,backimage.png"
       color="blue"
       opacity="0.5"
       shadow>
      </a-box>
   
   <!-- METHOD 2 -->   
      
   <!-- If you want to assign assets to only particular sides, the 'srcx' attribute can be more targeted -->
      
   <!-- The following example will only add textures to the left and right hand sides -->
      
      <a-box 
       position="0 1.5 -2" 
       multisrc="src0:#right;src1:#left"
       color="blue"
       opacity="0.5"
       shadow>
      </a-box>
      
    <!-- or this would add textures to the top and front -->
      
      <a-box 
       position="0 1.5 -2" 
       multisrc="src2:#top;src4:#front"
       color="blue"
       opacity="0.5"
       shadow>
      </a-box>
      
    <!-- etc. and you can assign images inline and with srcspath using this method as well -->
           
    </a-scene>
  </body>

Examples here are shown using images but as with the standard src attribute we can also use videos as a texture. The logic for playback on video textures (and how it differs between those defined inline or within assets) on multisrc is the same as that for video textures on standard src - see here for details. Basically, preloading is always the best way to do it.

API

Property Description Default
srcs Comma separated list of assets. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. []
srcspath For use with inline assets, saves you having to write the full image path each time (see above for example) ''
src0 Name of asset. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. As an alternative to srcs you can assign assets directly to specific sides. See below diagram of where numbered sides will end up on your shape. src0 could be used on any shape ''
src1 Name of asset. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. src1 can currently be set on cubes, cylinders and cones ''
src2 Name of asset. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. src2 can currently be set on cubes and cylinders ''
src3 Name of asset. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. src3 can currently be set on cubes ''
src4 Name of asset. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. src4 can currently be set on cubes ''
src5 Name of asset. Can either be a selector to an <img> or <video> defined in assets, or an inline URL. src5 can currently be set on cubes ''

Notes

The srcs attribute assumes the following order of your textures - positive-x, negative-x, positive-y, negative-y, positive-z, negative-z so in the case of a cube, it will place your first asset on the positive-x side (right), the second on the negative-x side (left) and so on.

The src0, src1, etc. attributes follow the same order. See diagram below which hopefully makes this clearer.

Multisrc order of images explainer

Usage

Install and use directly with the link in the below example (below example uses the src0, src1 etc. approach, see above for alternative srcs method.

  <head>
    <script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
    <script src="https://cdn.rawgit.com/elbobo/aframe-multisrc-component/b6d23310/dist/0.3/aframe-multisrc-component.js"></script>
  </head>
  <body>
    <a-scene>
      <a-assets>
        <img id="right" src="path/to/rightimage.png">
        <img id="left" src="path/to/leftimage.png">
        <img id="top" src="path/to/topimage.png">
        <img id="bottom" src="path/to/bottomimage.png">
        <img id="front" src="path/to/frontimage.png">
        <img id="back" src="path/to/backimage.png">
      </a-assets>
      <a-box 
        position="0 1.5 -2" 
        multisrc="src0:#right;src1#left;src2:#top;src3:#bottom;src4:#front;src5:#back"
        color="blue"
        opacity="0.5"
        shadow>
      </a-box>
    </a-scene>
  </body>

Advanced

Under the hood multisrc is adding a different material to each 'side' of a shape. This is made from an array of materials that three.js now allows to be added to the mesh Please see here for SO answer and discussion that prompted this approach.

Aside from the src attribute, these materials inherit properties from the default material component added to the entity so as to make its usage familiar. I think the most common use case of this is to apply different textures so I have made manipulating this declarative so it is straightforward to use for the most common case. You can however target the individual materials and effect other properties programatically. I have included a function that allows you to make granular changes should you wish to.

Materials are kept in an array in the standard order for applying materials, so individual materials can be reached by their index i.e. 0 = positive-x, 1 = negative-x, 2 = positive-y etc.

So, assuming you have multisrc attached to an element with id 'foo' you could use the granularChange function to target the right hand side material on a cube and change its colour like so;

var foo = document.getElementById('foo').components.multisrc
foo.granularChange(0).color = {r:0,g:1,b:0}

Or get the back and change its metalness

foo.granularChange(5).metalness = 0.8

Or get the right and make it a wireframe

 foo.granularChange(1).wireframe = true

etc. Which would result in the following on an otherwise blue cube with 0 metalness.

Multisrc granular changes demo image

NB if you change the default material's properties at any point with setAttribute or similar, these granular changes will be overwritten.

Known issues

In terms of figuring out how many sides a shape has (and applying textures accordingly) this currently works as well as the standard src attribute would i.e. it gets it right on cubes, cylinders, cones, triangles, circles etc. but not on more complex shapes like dodecahedron etc. I'm not going to list them all here but assume if you get unexpected results with a texture using standard src it will do the same with multisrc maybe I could handle this better at some point.

About

An A-frame component that allows you to add multiple material sources

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published