0

the flow I'm expecting:

  1. on page load, render the silhouette of an image
  2. enter a guess in the text field or hit the button to show the image from the silhouette
  3. fetch a new image and re-render the page with the silhouette of the new image

the issue is that the silhouette being rendered is that of the previous image, not the image from the current api response
it is evident when the page loads because the silhouette & picture are blank the first time
the new silhouette is not showing when you hit next because the old silhouette didnt go away

either:

  1. there is a mistake in the async await logic and syntax
  2. the DOM div is not getting updated correctly because of the async
  3. there is some problem with how the image elements are behaving
  4. there is a problem with the setting and getting HTML objects
  5. any other problem Im not seeing

what I have tried:

in the code, I have tried setting document.getElementById("sourceImg") and document.getElementById("silhouetteImg") directly after async instead of their vars sourceImg and silhouetteImg at lines 59 and 69, it didnt seem to change anything

also, I didnt setTimeout for the last function in the async callback, it didnt make a difference

also, I have tried Auto refresh images in HTML, it didnt make a difference

the api has some incomplete data, just skip all the null responses during testing if you are getting null/broken image
(plain javascript open in a full page)

<!DOCTYPE html>
<head>
   <style>
            body {
                font-family: monospace;
            }
      .centered {
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                font-size: 24px;
            }
            #footer {
                position: fixed;
                bottom:0;
                left: 0;
                right:0;
                text-align: center;
            }
   </style>
   <script>
            var id
            var name
            var sourceImg = document.createElement('img');
            sourceImg.setAttribute('id', "sourceImg");
            sourceImg.setAttribute('crossorigin', "anonymous");

            var silhouetteImg = document.createElement('img');
            silhouetteImg.setAttribute('id', "silhouetteImg");
            silhouetteImg.setAttribute('crossorigin', "anonymous");
            // + "?" + new Date().getTime() crossorigin="anonymous"
            function randomInteger(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
        }

            function getSilhouette(){
                var canvas = document.createElement("canvas");
                var ctx = canvas.getContext('2d');
                if (sourceImg.width != 0){
        //credit: https://dominoc925.blogspot.com/2012/08/javascript-example-code-to-create.html
                canvas.width = sourceImg.width;
                canvas.height = sourceImg.height;
                ctx.drawImage(sourceImg,0,0);
                var imgData = ctx.getImageData(0,0,canvas.width,canvas.height);
                var pix = imgData.data;
                //convert the image into a silhouette
                for (var i=0, n = pix.length; i < n; i+= 4){
                        //set red to 0
                        pix[i] = 0;
                        //set green to 0
                        pix[i+1] = 0;
                        //set blue to 0
                        pix[i+2] = 0;
                        //retain the alpha value
                        pix[i+3] = pix[i+3];
                }
                ctx.putImageData(imgData,0,0);
                silhouetteImg.src = canvas.toDataURL();
            }
            };

      async function getPokemon() {
                let response = await fetch('https://pokeapi.co/api/v2/pokemon/' + randomInteger(1,809));
                let data = await response.json();
                //if (null == data["sprites"]["other"]["official-artwork"]["front_default"]){getPokemon()}
                id = data["id"]
                name = data["name"]
                sourceImg.src = data["sprites"]["other"]["official-artwork"]["front_default"];
                console.log("new: " + id + " " + name + " " + sourceImg.src + " " + sourceImg.width + " " + sourceImg.height);
            };

            async function showOrNext(){
                if (document.getElementById("showOrNext").innerHTML == "Show"){
                    // reveal the pokemon
                    document.getElementById("pokemon").src = sourceImg.src;
                    document.getElementById("answer").innerHTML = name + " ";
                    document.getElementById("link").innerHTML = "View on Bulbapedia";
                    document.getElementById("link").href = "https://bulbapedia.bulbagarden.net/wiki/" + name + "_(Pok%C3%A9mon)";
                    document.getElementById("result").innerHTML = "";
                    document.getElementById("myInput").type = "hidden";
                    document.getElementById("showOrNext").innerHTML = "Next";
                    document.getElementById("showOrNext").focus();
                } else {
                    // get a new pokemon
                        await getPokemon().then(getSilhouette()).then(setTimeout(function(){
                        document.getElementById("pokemon").src = silhouetteImg.src;
                        document.getElementById("answer").innerHTML = "";
                        document.getElementById("link").innerHTML = "";
                        document.getElementById("result").innerHTML = "";
                        document.getElementById("myInput").type = "text";
                        document.getElementById("myInput").value = "";
                        document.getElementById("myInput").focus();
                        document.getElementById("showOrNext").innerHTML = "Show";
                    }), 1)
                };
            }

            window.onload = function() {
                showOrNext()
            };

            window.addEventListener("keyup", function(e) {
                if (e.keyCode === 13 && document.getElementById("myInput").type != "hidden") {
                    if (name === document.getElementById("myInput").value){
                            showOrNext();
                            document.getElementById("result").innerHTML = "<span style='color: green;'>Correct</span>";
                        } else {
                            document.getElementById("result").innerHTML = "<span style='color: red;'>Wrong</span>";
                        }
                }
            }, false);
     </script>
     
</head>
<body>
    <div class="centered">
            <img id="pokemon" crossorigin="anonymous">
            <center>
            <p><label id="answer"></label><a id="link" target="_blank"></a></p>
            <input id="myInput" type="text" onblur="this.focus()" autofocus>
            <button id="showOrNext" onclick="showOrNext()"></button>
            <p><label id="result"></label></p>
            </center>
        </div>
        <div id="footer">Pokémon and Pokémon character names are trademarks of Nintendo. This site is not affiliated with Nintendo.</div>
</body>
Ridhwaan Shakeel
  • 981
  • 1
  • 20
  • 39

1 Answers1

1

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <style>
      body {
        font-family: monospace;
      }

      .centered {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 24px;
      }

      #footer {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        text-align: center;
      }
      #pokemon {
        width: 40px;
        height: 40px;
      }
    </style>
    <script>
      var id;
      var name;

      var sourceImg = document.createElement("img");
      sourceImg.setAttribute("id", "sourceImg");
      sourceImg.setAttribute("crossorigin", "anonymous");

      var silhouetteImg = document.createElement("img");
      silhouetteImg.setAttribute("id", "silhouetteImg");
      silhouetteImg.setAttribute("crossorigin", "anonymous");

      function randomInteger(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
      }

      function getSilhouette() {
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");

        canvas.width = sourceImg.width;
        canvas.height = sourceImg.height;
        ctx.drawImage(sourceImg, 0, 0);
        var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        var pix = imgData.data;
        for (var i = 0, n = pix.length; i < n; i += 4) {
          //set red to 0
          pix[i] = 0;
          //set green to 0
          pix[i + 1] = 0;
          //set blue to 0
          pix[i + 2] = 0;
          //retain the alpha value
          pix[i + 3] = pix[i + 3];
        }
        ctx.putImageData(imgData, 0, 0);
        silhouetteImg.src = canvas.toDataURL();
        silhouetteImg.onload = () => {
          document.getElementById("pokemon").src = silhouetteImg.src;
          document.getElementById("answer").innerHTML = "";
          document.getElementById("link").innerHTML = "";
          document.getElementById("result").innerHTML = "";
          document.getElementById("myInput").type = "text";
          document.getElementById("myInput").value = "";
          document.getElementById("myInput").focus();
          document.getElementById("showOrNext").innerHTML = "Show";
        };
      }

      async function getPokemon() {
        let response = await fetch(
          "https://pokeapi.co/api/v2/pokemon/" + randomInteger(1, 809)
        );
        let data = await response.json();
        //if (null == data["sprites"]["other"]["official-artwork"]["front_default"]){getPokemon()}

        id = data["id"];
        name = data["name"];
        sourceImg.src =
          data["sprites"]["other"]["official-artwork"]["front_default"];
        sourceImg.onload = () => {
          getSilhouette();
        };
      }

      function showOrNext() {
        if (document.getElementById("showOrNext").innerHTML === "Show") {
          // reveal the pokemon
          document.getElementById("pokemon").src = sourceImg.src;
          document.getElementById("answer").innerHTML = name + " ";
          document.getElementById("link").innerHTML = "View on Bulbapedia";
          document.getElementById("link").href =
            "https://bulbapedia.bulbagarden.net/wiki/" +
            name +
            "_(Pok%C3%A9mon)";
          document.getElementById("result").innerHTML = "";
          document.getElementById("myInput").type = "hidden";
          document.getElementById("showOrNext").innerHTML = "Next";
          document.getElementById("showOrNext").focus();
        } else {
          // get a new pokemon
          getPokemon();
        }
      }

      window.addEventListener(
        "keyup",
        function (e) {
          if (
            e.keyCode === 13 &&
            document.getElementById("myInput").type !== "hidden"
          ) {
            if (name === document.getElementById("myInput").value) {
              showOrNext();
              document.getElementById("result").innerHTML =
                "<span style='color: green;'>Correct</span>";
            } else {
              document.getElementById("result").innerHTML =
                "<span style='color: red;'>Wrong</span>";
            }
          }
        },
        false
      );

      window.addEventListener("DOMContentLoaded", (event) => {
        console.log("DOM fully loaded and parsed");
        showOrNext();
      });
    </script>
  </head>

  <body>
    <div class="centered">
      <img id="pokemon" crossorigin="anonymous" />
      <center>
        <p>
          <label id="answer"></label>
          <a id="link" target="_blank"></a>
        </p>
        <input id="myInput" type="text" onblur="this.focus()" autofocus />
        <button id="showOrNext" onclick="showOrNext()"></button>
        <p><label id="result"></label></p>
      </center>
    </div>
    <div id="footer">
      Pokémon and Pokémon character names are trademarks of Nintendo. This site
      is not affiliated with Nintendo.
    </div>
  </body>
</html>
deepak
  • 1,390
  • 1
  • 8
  • 12