the flow I'm expecting:
- on page load, render the silhouette of an image
- enter a guess in the text field or hit the button to show the image from the silhouette
- 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:
- there is a mistake in the async await logic and syntax
- the DOM div is not getting updated correctly because of the async
- there is some problem with how the image elements are behaving
- there is a problem with the setting and getting HTML objects
- 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>