Welcome to today’s tutorial. Today we are going to create a random pokemon card generator. For this, we will use HTML, CSS and Javascript. Apart from this, we will also be using the poke API to get the necessary data.
The poke Card generator consists of a button called – ‘Generate’. When the user clicks on this button a card is displayed with a random pokemon name, image and other stats. For this project, I will suggest you are comfortable with ES6. This is a great project for javascript intermediates and people who are trying to experiment with Fetch API.
Video Tutorial:
I have a video version of this tutorial on my youtube channel. If you would like to code along with me, do check it down below.
Project Folder Structure:
Let us take a quick look at the project structure. We have a project folder called – Pokemon Card Generator
. Inside this folder, we have three files. The first one is the HTML document called index.html
. Next one is the stylesheet named style.css
, and the last one is the script file called script.js
.
HTML:
The HTML consists of a container
div that wraps the card
div and the button
element. We don’t have many other elements in HTML code as we will be generating them using Javascript.
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Pokemon Card Generator</title> <!-- Google Fonts --> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet" /> <!-- Stylesheet --> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="container"> <div id="card"></div> <button id="btn">Generate</button> </div> <!-- Script --> <script src="script.js"></script> </body> </html>
CSS:
Coming to the CSS Code, we do a CSS reset by removing the unwanted paddings and margins. We also centre the container
using the transforms. We set the dimensions for the container and the card
div.
For the pokemon image we set the width
to 180px and max-height
to 200px.
We style the span
elements and place them inside the types div using the flex layout. We set the justify-content
to space-around
.
Similarly, we style the stats div and the button.
* { padding: 0; margin: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { background-color: #eff3ff; } .container { width: 350px; position: absolute; transform: translate(-50%, -50%); top: 50%; left: 50%; } #card { position: relative; width: 100%; padding: 30px 20px; box-shadow: 0 20px 30px rgba(0, 0, 0, 0.15); border-radius: 10px; } #card img { display: block; width: 180px; max-height: 200px; position: relative; margin: 20px auto; } .hp { width: 80px; background-color: #ffffff; text-align: center; padding: 8px 0; border-radius: 30px; margin-left: auto; font-weight: 400; } .poke-name { text-align: center; font-weight: 600; } .types { display: flex; justify-content: space-around; margin: 20px 0 40px 0; } .hp span, .types span { font-size: 12px; letter-spacing: 0.4px; font-weight: 600; } .types span { padding: 5px 20px; border-radius: 20px; color: #ffffff; } .stats { display: flex; align-items: center; justify-content: space-between; text-align: center; } .stats p { color: #404060; } #btn { display: block; padding: 15px 60px; font-size: 18px; background-color: #101010; color: #ffffff; position: relative; margin: 30px auto; border: none; border-radius: 5px; }
Javascript:
Now coming to javascript, we create an array for colours corresponding to each pokemon type. Next, we store the pokeAPI link in a constant called URL
. We also get the card
and btn
elements and assign them to variables.
In the next step, we create a function called getPokeData
. Within this function, we generate a random number between 1 and 150. This number will be our id.
We create the finalUrl
by combining the URL
and the id
string. Now we fetch the data for the pokemon corresponding to the id generated. We use this data to create the card.
For the next step, we create a function called generateCard()
. Now using the data fetched from the API we get necessary data and assign them to variables.
We now use the pokemon type to get a corresponding color value from the typeColor
array. Now we assign this value to a variable called themeColor
.
Next, we generate HTML for the card using variables we have created. At this point, we call the function appendTypes
with the parameter data.types
.
The appendTypes
function iterates over the types array and wrap each type inside a span element. This span
element is then appended to the types
div.
We also call the styleCard
function which applies the themeColor
to the card background as radial-gradient and the span element inside the types div. And that’s it. Our random pokemon Card generator is now ready.
const typeColor = { bug: "#26de81", dragon: "#ffeaa7", electric: "#fed330", fairy: "#FF0069", fighting: "#30336b", fire: "#f0932b", flying: "#81ecec", grass: "#00b894", ground: "#EFB549", ghost: "#a55eea", ice: "#74b9ff", normal: "#95afc0", poison: "#6c5ce7", psychic: "#a29bfe", rock: "#2d3436", water: "#0190FF", }; const url = " https://pokeapi.co/api/v2/pokemon/"; const card = document.getElementById("card"); const btn = document.getElementById("btn"); let getPokeData = () => { // Generate a random number between 1 and 150 let id = Math.floor(Math.random() * 150) + 1; // Combine the pokeapi url with pokemon id const finalUrl = url + id; // Fetch generated URL fetch(finalUrl) .then((response) => response.json()) .then((data) => { generateCard(data); }); }; //Generate Card let generateCard = (data) => { // Get necessary data and assign it to variables console.log(data); const hp = data.stats[0].base_stat; const imgSrc = data.sprites.other.dream_world.front_default; const pokeName = data.name[0].toUpperCase() + data.name.slice(1); const statAttack = data.stats[1].base_stat; const statDefense = data.stats[2].base_stat; const statSpeed = data.stats[5].base_stat; // Set themeColor based on pokemon type const themeColor = typeColor[data.types[0].type.name]; console.log(themeColor); card.innerHTML = ` <p class="hp"> <span>HP</span> ${hp} </p> <img src=${imgSrc} /> <h2 class="poke-name">${pokeName}</h2> <div class="types"> </div> <div class="stats"> <div> <h3>${statAttack}</h3> <p>Attack</p> </div> <div> <h3>${statDefense}</h3> <p>Defense</p> </div> <div> <h3>${statSpeed}</h3> <p>Speed</p> </div> </div> `; appendTypes(data.types); styleCard(themeColor); }; let appendTypes = (types) => { types.forEach((item) => { let span = document.createElement("SPAN"); span.textContent = item.type.name; document.querySelector(".types").appendChild(span); }); }; let styleCard = (color) => { card.style.background = `radial-gradient(circle at 50% 0%, ${color} 36%, #ffffff 36%)`; card.querySelectorAll(".types span").forEach((typeColor) => { typeColor.style.backgroundColor = color; }); }; btn.addEventListener("click", getPokeData); window.addEventListener("load", getPokeData);
This is very good!
really a great and fun project!! but I just have one problem…the images(sprites) are not loading….can you help please!!