Image will not load when dynamically added using JS

In my AR experience, I want a textbox to open up when I tap a hotspot. This textbox needs to present images with information. Snippet form my HTML is as follows:

<div id="container" class="collapsed">
  <div class="outer">
    <div id="closeButton" onclick="hideAll()">Close</div>
  </div>
  <div class="outer" id="contents"></div>
</div>

I want to dynamically add the innerHTML for this div id=“contents” from my tap-hotspot.js. Here is the HTML snippet for a hotspot:

<a-entity
    id="model"
    gltf-model="#campusModel"
    scale="0.5 0.5 0.5"
    visible="false"
    shadow="receive: false"
    xrextras-hold-drag
    xrextras-two-finger-rotate
    xrextras-pinch-scale
    reflections="type: realtime">
    <a-entity id="ActivitiesAndLandmarks" visible="true">
      <!--Hotspot #1-->
      <!-- id NEEDS TO MATCH THE KEY IN hotspotDescriptions -->
      <a-entity
        id="JCSU"
        mixin="hotspot-target"
        position="-0.5 1.3 -0.3"
        rotation="0 0 0"
        scale="1 1 1"
        look-at="#camera"
        class="cantap"
        tap-hotspot>
        <!-- id NEEDS TO MATCH THE format: "{a-entity id}-child" -->
        <!-- value needs to be whatever you want the title to be in the text -->
        <a-text
          id="JCSU-child"
          value="Joe Crowley Student Union"
          align="center"
          mixin="hotspot-text"
          visible="false"
          tap-close></a-text>
      </a-entity>

I am trying to dynamically add the text and images to this textbox based on which hotspot is clicked. The text shows up just fine but the images just show up as placeholders. Here is my tap-hotspot.js:

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 hotspotDescriptions = {
      MIKC: [
        {type: 'text', content: 'Looking for help with research or just a comfortable place to study?'},
        {type: 'image', content: 'assets/mikc_1.jpg'},
        {type: 'text', content: 'Completed in 2008, the Mathewson-IGT Knowledge Center features the technology, spaces, and services you need. Computing and information technologies and support are combined with the latest in multimedia tools and the resources of the University library in a physical environment designed for comfort, efficiency and collaboration.'},
      ],
.........

    const handleClickEvent = (e) => {
      container.classList.remove('collapsed')
      childElement.setAttribute('visible', true)
      childElement.setAttribute('class', 'cantap')

      this.el.sceneEl.emit('dismissPrompt2')

      const title = childElement.getAttribute('value')

      const sections = hotspotDescriptions[id] || [{type: 'text', content: 'No additional information available.'}]
      let contentHTML = `<h3>${title}</h3>`

      // Loop through sections to construct content
      sections.forEach((section) => {
        if (section.type === 'text') {
          contentHTML += `<p>${section.content}</p>`
        } else if (section.type === 'image') {
          console.log(section.content)
          contentHTML += `<img src="${section.content}" alt="Hotspot Image" />`
          // contentHTML += '<img src="assets/mikc_1.jpg" alt="MIKC" />'
        }
      })

      contents.innerHTML = contentHTML

      // Dynamic plane resizing based on text length
      const textLength = title.length
      const planeWidth = Math.max(1.6, textLength * 0.12)  // Adjust multiplier as needed

      // Adjust the plane dynamically
      childElement.setAttribute('geometry', `primitive: plane; width: ${planeWidth}; height: 0.4`)

      this.el.setAttribute('material', 'color: rgb(5, 44, 255)')  // Highlight selected hotspot
      window.lastSelectedHotspot = this.el

      setTimeout(() => {
        const handleOutsideClick = (event) => {
          if (!container.contains(event.target) && !this.el.contains(event.target)) {
            hideAll()
            this.el.sceneEl.emit('showPrompt3')
            window.removeEventListener('click', handleOutsideClick)
          }
        }
        window.addEventListener('click', handleOutsideClick)
      }, 100)
    }

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

export {tapHotspotComponent}

I tried statically loading an image directly from HTML and it loads just fine using this line within my div id=“contents”:

<img src="assets/mikc_1.jpg" alt="MIKC" />

Here is my folder structure:

Why am I not able to see my images when I update it from my tap-hotspot.js?

Try wrapping the asset path with require():

1 Like

This worked! Thank you!

1 Like

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.