Search code examples
javascripthtmlimagebuttonhtml5-canvas

Connecting an <a> element to draw an image in a HTML canvas


I am trying to use a dropdown button list to display different images in a HTML canvas. I have the href set to utilize javascript and the img and script down by the canvas, yet when you click on the button nothing happens. Am I missing something in the coding, or is there a better way to go about this? I appreciate the input!

`<div class="dropdown">
              <button onclick="adultlist()" class="dropbtn">Adults</button>
              <div id="adults" class="dropdown-content">
                  <a href = "javascript:drawa1();">Adult 1</a> 
                  <a href = "#canvas">Adult 2</a> 
                  <a href = "#canvas">Adult 3</a> 
                  <a href = "#canvas">Adult 4</a> 
                  <a href = "#canvas">Adult 5</a> 
                  <a href = "#canvas">Adult 6</a>
                  <a href = "#canas">Adult 7</a> 
                  <a href = "#canvas">Adult 8</a> 
                  <a href = "#canvas">Adult 9</a> 
                  <a href = "#canvas">Adult 10</a>
                </div>
            </div>
            <script>
        function adultlist() {
         document.getElementById("adults").classList.toggle("show");
         }
         window.onclick = function(event) {
         if (!event.target.matches('.dropbtn')) {
         var dropdowns = document.getElementsByClassName("dropdown-content");
         var i;
         for (i = 0; i < dropdowns.length; i++) {
         var openDropdown = dropdowns[i];
         if (openDropdown.classList.contains('show')) {
         openDropdown.classList.remove('show');
               }
             }
           }
         }
              </script>

 <img id="adult1" width="100" height="290" src="SILHOUETTE PNG'S/silhouette_adult1.png"       alt="Adult 1" class="hidden">
    <canvas class="preview" id="canvas" width="250" height="300"> 
      Your browser does not support the HTML canvas tag.
    </canvas>
<script>
    function drawa1() {
          var c = document.getElementById("canvas");
          var ctx= canvas.getContext("2d");
          const img= document.getElementById("adult1").innerHTML = img;
          ctx.drawImage(img,10,10);
      };
      </script>``

Solution

  • The main issue with your code are in these lines:

    const img = document.getElementById("adult1").innerHTML = img;
    ctx.drawImage(img, 10, 10);
    

    Firstly, you're assigning a variable to the innerHTML of an element then to itself, which makes no sense. You need to set img to the reference of the img element so that it can be provided to the drawImage() method.

    There's also a few other improvements you could make, such as removing the event handlers from the HTML, and relating the a elements to the images by their index within the container, instead of having to explicitly assign classes or ids to everything.

    Here's a working example with those changes made:

    window.addEventListener('click', e => {
      if (e.target.matches('.dropbtn'))
        return;
    
      var dropdowns = document.querySelectorAll(".dropdown-content");
      dropdowns.forEach(dropdown => dropdown.classList.toggle('show'));
    });
    
    const dropBtn = document.querySelector('.dropbtn');
    const adultsContainer = document.querySelector('#adults');
    const adults = adultsContainer.querySelectorAll('a');
    const images = document.querySelectorAll('.images-container img');
    const canvas = document.querySelector('#canvas');
    const ctx = canvas.getContext("2d");
    
    const getIndexWithinParent = el => [...el.parentElement.children].indexOf(el);
    
    dropBtn.addEventListener('click', () => {
      adultsContainer.classList.toggle("show");
    });
    
    adults.forEach(adult => {
      adult.addEventListener('click', e => {
        e.preventDefault();
        ctx.fillStyle = 'rgba(0, 0, 0, 0)';
        ctx.fillRect(0, 0, canvas.width, canvas.height); // clear existing images
        
        const img = images[getIndexWithinParent(e.target)];
        ctx.drawImage(img, 10, 10);
      });
    });
    #adults,
    .images-container {
      display: none;
    }
    
    #adults.show {
      display: block;
    }
    <div class="dropdown">
      <button class="dropbtn">Adults</button>
      <div id="adults" class="dropdown-content">
        <a href="#">Adult 1</a>
        <a href="#">Adult 2</a>
        <a href="#">Adult 3</a>
      </div>
    </div>
    
    <div class="images-container">
      <img width="100" height="290" src="https://dummyimage.com/100x290/ccc/fff.png&text=Adult+1" alt="Adult 1" />
      <img width="100" height="290" src="https://dummyimage.com/100x290/ccc/fff.png&text=Adult+2" alt="Adult 1" />
      <img width="100" height="290" src="https://dummyimage.com/100x290/ccc/fff.png&text=Adult+3" alt="Adult 1" />
    </div>
    
    <canvas class="preview" id="canvas" width="250" height="300"> 
      Your browser does not support the HTML canvas tag.
    </canvas>