How to add a clickable object to an array of models in AFRAME

Viewed 242

I'm trying to add a sort of hotspot to each swappable 3d model, so when the user clicks the hotspot through the screen, it shows the information. I'm trying to add the hotspot components to the next-button javascript file. I understand that in the next-button.js file I'm calling for the id='model' but I would like to call all the models so I can place on each of them a particular hotspot. Any idea how I can make it happen? Thanks! =)

Here is the HTML code

'''<!-- Swap Next Model -->

<div id="nextbutton" style="display: none; z-index: 10">
  <h2>Next 3D Model</h2>
</div>

<!-- Hotspot Project -->

<div id="recenterButtonContainer" class="hidden">
  <img src="./assets/images/recenter.png">
</div>

<div id="container" class="collapsed">
  <div class="outer">
    <div id="closeButton" onclick="hideAll()">Close</div>
  </div>
  <div class="outer" id="contents"></div>
  <!--<div class="outer">Contents go here</div>-->
</div>

<a-scene 
  
  next-button
  tap-place
  xrextras-gesture-detector
  xrextras-almost-there
  xrextras-loading
  xrextras-runtime-error
  xrextras-pause-on-hidden
  renderer="maxCanvasWidth: 960; maxCanvasHeight: 960;colorManagement: true"
  xrface="
          cameraDirection: back;
          allowedDevices: any;"
  >

  <!-- We can define assets here to be loaded when A-Frame initializes -->
  <a-assets>
    <!-- Credit to Poly by Google for the model: https://poly.google.com/view/7rUkCX-AIR2 -->
    <a-asset-item id="humanModel" src="assets/models/human-hand.glb"></a-asset-item>
    <a-asset-item id="grassModel" src="assets/models/grass-hand.glb"></a-asset-item>
    <a-asset-item id="dirtyModel" src="assets/models/dirty-hand.glb"></a-asset-item>
    <a-asset-item id="heartModel" src="assets/models/heart.glb"></a-asset-item>

  </a-assets>

 <a-assets>
     <audio id="ukulele-music" preload="auto" class="a-sound" src="./assets/ukulele.mp3" response-type="arraybuffer"></audio>
  </a-assets>

  <xrextras-capture-config></xrextras-capture-config>
  
 <a-camera position="0 1 3">
    <a-entity sound="src: #ukulele-music; loop: true; volume: 0.3;"></a-entity>
 </a-camera>

  <!-- The raycaster will emit mouse events on scene objects specified with the cantap class -->
  <a-camera
    id="camera"
    position="0 4 6"
    raycaster="objects: .cantap"
    cursor="fuse: false; rayOrigin: mouse;">
  </a-camera>

<!-- Hotspot -->
  <a-assets>
    <!-- Credit to Poly by Google for the model: https://poly.google.com/view/7rUkCX-AIR2 -->
    <a-asset-item id="handModel" src="assets/models/human-hand.glb"></a-asset-item>
    <a-mixin id="hotspot-text" text="font: exo2bold; width: 5" geometry="primitive: plane; width: 1.6; height: 0.4" material="color: black;" position="0 0.5 0"></a-mixin>
    <a-mixin id="hotspot-target" geometry="primitive: octahedron; radius: 0.2;" material="flatShading: true; color: rgb(255, 0, 161)"></a-mixin>
  </a-assets>

  <a-entity
    light="
      type: directional;
      intensity: 0.8;
      castShadow: true;
      shadowMapHeight:2048;
      shadowMapWidth:2048;
      shadowCameraTop: 10;
      target: #model;"
    xrextras-attach="target: model; offset: 1 15 3;"
    shadow>
  </a-entity>

  <a-light type="ambient" intensity="0.7"></a-light>

  <a-entity 
    id="model"
    gltf-model="#humanModel" 
    class="cantap" 
    xrextras-hold-drag
    xrextras-two-finger-rotate 
    xrextras-pinch-scale
    scale="50 50 50" 
    shadow="receive: false">

    <!--Hotspot #1-->
    <a-entity id="hotspot1" mixin="hotspot-target" position="-0.515 0.505 0.969" rotation="0 0 0" scale="0.5 0.5 0.5" look-at="#camera" class="cantap" tap-hotspot>
      <a-text id="hotspot1-child" value="Hotspot 1" align="center" mixin="hotspot-text" visible="false" tap-close></a-text>
    </a-entity>

  </a-entity>
  <a-plane
    id="ground" 
    rotation="-90 0 0" 
    width="1000" 
    height="1000" 
    material="shader: shadow" 
    shadow>
  </a-plane>
</a-scene>'''

Here is the next-button.js code

'''// Copyright (c) 2021 8th Wall, Inc.

const nextButtonComponent = () => ({
  init() {
    const modelList = ['humanModel', 'grassModel', 'dirtyModel']
    const model = document.getElementById('model')
    const nextButton = document.getElementById('nextbutton')
    nextButton.style.display = 'block'

    let idx = 1  // Start with the 2nd model as 1st is already in the scene on page load
    const nextModel = () => {
      // Need to remove gltf-component first due to AFrame regression: https://github.com/aframevr/aframe/issues/4341
      model.removeAttribute('gltf-model')
      // Switch to next model in the list
      model.setAttribute('gltf-model', `#${modelList[idx]}`)

      idx = (idx + 1) % modelList.length
    }
    nextButton.onclick = nextModel  // Switch to the next model when the button is pressed.
  },
})
export {nextButtonComponent} '''

The hotspot component js file

'''const tapHotspotComponent = {
  init() {
    const id = this.el.getAttribute('id')
    const contents = document.getElementById('contents')
    const container = document.getElementById('container')
    const childElement = document.getElementById(`${id}-child`)

    const handleClickEvent = (e) => {
      hideAll()
      container.classList.remove('collapsed')
      childElement.setAttribute('visible', true)
      childElement.setAttribute('class', 'cantap')
      const title = childElement.getAttribute('value')
      contents.innerHTML = `<h1>${title}</h1>More info about ${title} goes here.`
    }

    this.el.addEventListener('click', handleClickEvent, true)
  },
}

export {tapHotspotComponent} '''
0 Answers
Related