IMG tag in svg is not working when only id and class is provided

Issue

The HTML code below shows the HTML code where I am using SVG to display pictures and then polygons on the pictures and this is done with D3 using image pagination.

Somehow the images are displayed if I am using an main tag outside of the SVG with the same id and class but as soon as I keep it inside SVG itS displays the SVG BOX but not the image inside the SVG

the reason why i have a main tag can be understood if showImages() function is referred from the javascript code

The javascript code shows how the id and classes are being used in the HTML code.
Also, I want the image to be displayed with its original size and scale so what input should I provide to the SVG tag and img tag in terms of height and width to prevent it from changing the size of the image.

I really need to get this done, this is the last time of my task.
Please help me!

        <div class="gallery">
<main id="image-gallery" class="images">  </main> 
<svg width="500" height="500">
  <polygon  id='x' style="stroke:#f00; fill:none;" /> 
</svg>

     </div>

             var width=400;
             var height=400;
             var padding=2;
             var Data;
             var arr;
             var s;
             var images= [];
             var txt= [];
             var txtfiles
            var annotationpath;
            var previous = document.getElementById('btnPrevious');
            var next = document.getElementById('btnNext');
           var gallery = document.getElementById('image-gallery');
           var pageIndicator = document.getElementById('page');
           var pageIndicator = document.getElementById('page');
           var galleryDots = document.getElementById('gallery-dots');





      d3.text("100images.csv", "text/csv", function(unParsedData){
          Data = d3.csv.parse(unParsedData);

function txtfile(element, index, array){
  imge=array[index].image_url;
  arr=array[index].annotation;

 images.push({

source: imge

  });

  txt.push({
    source:arr
  });

 //console.log(arr);
  // images.push(imge); 
    
}


    
  

console.log("txt files are : \n");
Data.forEach(txtfile);

 


var perPage =1;
var page = 1;
var pages = Math.ceil(images.length / perPage)
console.log(pages);

  // // Gallery dots
  for (var i = 0; i < pages; i++){
    var dot = document.createElement('button')
    var dotSpan = document.createElement('span')
    var dotNumber = document.createTextNode(i + 1)
    dot.classList.add('gallery-dot');
    dot.setAttribute('data-index', i);
    dotSpan.classList.add('sr-only');
    
    dotSpan.appendChild(dotNumber);
    dot.appendChild(dotSpan)
    
    dot.addEventListener('click', function(e) {
      var self = e.target
      goToPage(self.getAttribute('data-index'))
    })
    
    galleryDots.appendChild(dot)
  }

  // Previous Button
     previous.addEventListener('click', function() {
    if (page === 1) {
      page = 1;
    } else {
      page--;
      showImages();
    }
  })
  
  // Next Button
  next.addEventListener('click', function() {
    if (page < pages) {
      page++;
      showImages();
    }
  })
  
  // Jump to page
  function goToPage(index) {
    index = parseInt(index);
    page =  index + 1;
    
    showImages();
  }

  // Load images
  function showImages() {
    while(gallery.firstChild) gallery.removeChild(gallery.firstChild)
    
    var offset = (page - 1) * perPage;
    var dots = document.querySelectorAll('.gallery-dot');
    
    for (var i = 0; i < dots.length; i++){
      dots[i].classList.remove('active');
    }
    
    dots[page - 1].classList.add('active');
    
    for (var i = offset; i < offset + perPage; i++) {
      if ( images[i],txt[i] ) {
        var template = document.createElement('div');
        var title = document.createElement('p');
        var titleText = document.createTextNode(images[i].title);
        var img = document.createElement('img');
        txtfiles=document.createElement('txtfiles');
        template.classList.add('template')
        img.setAttribute("src", images[i].source);
        img.setAttribute('alt', images[i].title);
        txtfiles.setAttribute("src",txt[i].source);
    
        annotationpath=txt[i].source;
       console.log(txt[i].source);
        title.appendChild(txtfiles);
        template.appendChild(img);
        template.appendChild(txtfiles);
        gallery.appendChild(template);   

        

async function fetchData(){
  await fetch(annotationpath)
    .then(response => response.text())
    .then(text => {
      s=text;  //s contains the content of the file
  console.log(s);

      
     var f = this.s.split(/\r\n|\n/);

      for(var line = 2; line < f.length; line++){ //array to loop through each lines an
  
     console.log(line + " --> "+f[line]);
      var annotationline = f[line].split(' '),
        x1= annotationline[0], y1 = annotationline[1], 
        
       x2= annotationline[2], y2 = annotationline[3],
       x3= annotationline[4], y3 = annotationline[5], 
       x4= annotationline[6], y4 = annotationline[7], 
       classes = annotationline[8], detected= annotationline[9];


  document.getElementById('x').setAttribute('points', x1 + "," + y2 + " " + x2 + "," + y2 + " "+ x3 + "," + y3 + " "+ x4 + "," + y4);

      

    
      
}
    
      
      })

}




    fetchData();

      }
    }
    
    // Animate images
    var galleryItems = document.querySelectorAll('.template')
    for (var i = 0; i < galleryItems.length; i++) {
      var onAnimateItemIn = animateItemIn(i);
      setTimeout(onAnimateItemIn, i * 100);
    }
    
    function animateItemIn(i) {
      var item = galleryItems[i];
      return function() {
        item.classList.add('animate');
      }
    }
    
    // Update page indicator
    pageIndicator.textContent = "Page " + page + " of " + pages;
    
  }
  





                              




showImages();

  })
 

Solution

Either the image can be displayed using the <img> element outside the SVG or using the <image> element inside the SVG. Here is an example of both where image and SVG are positioned absolute in the container.

.gallery {
  display: flex;
  gap: 10px;
}

.galleryimage {
  position: relative;
  width: 250px;
  height: 150px;
}

.galleryimage img {
  position: absolute;
}

.galleryimage svg {
  position: absolute;
}
<div class="gallery">
  <div class="galleryimage">
    <img src="https://via.placeholder.com/250x150.png" id="image-gallery" class="images" width="250" height="150"/>
    <svg width="250" height="150">
      <polygon id="x" points="30,30 200,40 100,120 50,110" style="stroke:#f00; fill:none;" /> 
    </svg>
  </div>

  <div class="galleryimage">
    <img src="https://via.placeholder.com/250x150.png" id="image-gallery" class="images" width="250" height="150"/>
    <svg width="250" height="150">
      <image href="https://via.placeholder.com/250x150.png" width="250" height="150"/>
      <polygon id="x" points="30,30 200,40 100,120 50,110" style="stroke:#f00; fill:none;" />
    </svg>
  </div>
</div>

Answered By – chrwahl

Answer Checked By – Candace Johnson (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.