Added a feature to display a dynamic list of pokemon that you can filter by type and generation
TODO: save current filters for page load, add popup page with info, make clickable cards, potential favourites system?
This commit is contained in:
		
							parent
							
								
									ed5c27f449
								
							
						
					
					
						commit
						636b43a261
					
				
							
								
								
									
										377
									
								
								css/styles.css
								
								
								
								
							
							
						
						
									
										377
									
								
								css/styles.css
								
								
								
								
							| 
						 | 
				
			
			@ -7,6 +7,24 @@
 | 
			
		|||
 | 
			
		||||
:root {
 | 
			
		||||
  --bgColor: #ffffff;
 | 
			
		||||
  --normal: #999999;
 | 
			
		||||
  --fighting: #C03028;
 | 
			
		||||
  --flying: #A890F0;
 | 
			
		||||
  --poison: #A040A0;
 | 
			
		||||
  --ground: #E0C068;
 | 
			
		||||
  --rock: #B8A038;
 | 
			
		||||
  --bug: #A8B820;
 | 
			
		||||
  --ghost: #705898;
 | 
			
		||||
  --steel: #B8B8D0;
 | 
			
		||||
  --fire: #F08030;
 | 
			
		||||
  --water: #6890F0;
 | 
			
		||||
  --grass: #78C850;
 | 
			
		||||
  --electric: #F8D030;
 | 
			
		||||
  --psychic: #F85888;
 | 
			
		||||
  --ice: #98D8D8;
 | 
			
		||||
  --dragon: #7038F8;
 | 
			
		||||
  --dark: #41314e;
 | 
			
		||||
  --fairy: #EE99AC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +100,7 @@ h1 {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.black {
 | 
			
		||||
  background-color: #000;
 | 
			
		||||
  background-color: #000; /* Reference[0] https://www.w3schools.com/howto/howto_css_cutout_text.asp */
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  mix-blend-mode: multiply;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -173,6 +191,357 @@ h3 {
 | 
			
		|||
  border-bottom: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* POKEDEX STYLES */
 | 
			
		||||
 | 
			
		||||
#pokedex {
 | 
			
		||||
  max-width: 1300px;
 | 
			
		||||
  margin: auto;
 | 
			
		||||
  margin-bottom: 50px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#generation-selector, #type-selector {
 | 
			
		||||
  overflow-x: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokedex h2 {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#generation-selector {
 | 
			
		||||
  display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#generation-selector input {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#generation-selector label {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
  min-height: 40px;
 | 
			
		||||
  min-width: 40px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  text-shadow: black 0px 0px 3px;
 | 
			
		||||
  line-height: 40px;
 | 
			
		||||
  border-radius: 30px;
 | 
			
		||||
  background-color: #202020;
 | 
			
		||||
  color: white;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  transition: background-color 0.5s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#generation-selector label:hover {
 | 
			
		||||
  background-color: #303030;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#generation-selector input:checked + label {
 | 
			
		||||
  background-color: var(--bgColor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#type-selector {
 | 
			
		||||
  display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#type-selector input {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#type-selector label {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
  height: 40px;
 | 
			
		||||
  width: 40px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  line-height: 40px;
 | 
			
		||||
  border-radius: 30px;
 | 
			
		||||
  background-color: #202020;
 | 
			
		||||
  color: white;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  transition: background-color 0.5s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#type-selector label img {
 | 
			
		||||
  width: 40px;
 | 
			
		||||
  height: 40px;
 | 
			
		||||
  font-size: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#type-selector label:hover {
 | 
			
		||||
  background-color: #303030;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#type-selector input:checked + label {
 | 
			
		||||
  background-color: var(--bgColor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#normal:checked + label {
 | 
			
		||||
  background-color: var(--normal) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#fighting:checked + label {
 | 
			
		||||
  background-color: var(--fighting) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#flying:checked + label {
 | 
			
		||||
  background-color: var(--flying) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#poison:checked + label {
 | 
			
		||||
  background-color: var(--poison) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ground:checked + label {
 | 
			
		||||
  background-color: var(--ground) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#rock:checked + label {
 | 
			
		||||
  background-color: var(--rock) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#bug:checked + label {
 | 
			
		||||
  background-color: var(--bug) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ghost:checked + label {
 | 
			
		||||
  background-color: var(--ghost) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#steel:checked + label {
 | 
			
		||||
  background-color: var(--steel) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#fire:checked + label {
 | 
			
		||||
  background-color: var(--fire) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#water:checked + label {
 | 
			
		||||
  background-color: var(--water) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#grass:checked + label {
 | 
			
		||||
  background-color: var(--grass) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#electric:checked + label {
 | 
			
		||||
  background-color: var(--electric) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#psychic:checked + label {
 | 
			
		||||
  background-color: var(--psychic) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ice:checked + label {
 | 
			
		||||
  background-color: var(--ice) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#dragon:checked + label {
 | 
			
		||||
  background-color: var(--dragon) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#dark:checked + label {
 | 
			
		||||
  background-color: var(--dark) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#fairy:checked + label {
 | 
			
		||||
  background-color: var(--fairy) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .normal-primary-type {
 | 
			
		||||
  background-color: var(--normal) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .normal-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--normal) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .fighting-primary-type {
 | 
			
		||||
  background-color: var(--fighting) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .fighting-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--fighting) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .flying-primary-type {
 | 
			
		||||
  background-color: var(--flying) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .flying-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--flying) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .poison-primary-type {
 | 
			
		||||
  background-color: var(--poison) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .poison-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--poison) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .ground-primary-type {
 | 
			
		||||
  background-color: var(--ground) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .ground-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--ground) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .rock-primary-type {
 | 
			
		||||
  background-color: var(--rock) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .rock-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--rock) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .bug-primary-type {
 | 
			
		||||
  background-color: var(--bug) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .bug-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--bug) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .ghost-primary-type {
 | 
			
		||||
  background-color: var(--ghost) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .ghost-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--ghost) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .steel-primary-type {
 | 
			
		||||
  background-color: var(--steel) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .steel-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--steel) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .fire-primary-type {
 | 
			
		||||
  background-color: var(--fire) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .fire-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--fire) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .water-primary-type {
 | 
			
		||||
  background-color: var(--water) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .water-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--water) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .grass-primary-type {
 | 
			
		||||
  background-color: var(--grass) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .grass-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--grass) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .electric-primary-type {
 | 
			
		||||
  background-color: var(--electric) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .electric-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--electric) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .psychic-primary-type {
 | 
			
		||||
  background-color: var(--psychic) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .psychic-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--psychic) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .ice-primary-type {
 | 
			
		||||
  background-color: var(--ice) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .ice-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--ice) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .dragon-primary-type {
 | 
			
		||||
  background-color: var(--dragon) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .dragon-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--dragon) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .dark-primary-type {
 | 
			
		||||
  background-color: var(--dark) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .dark-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--dark) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .fairy-primary-type {
 | 
			
		||||
  background-color: var(--fairy) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container .fairy-secondary-type {
 | 
			
		||||
  box-shadow: inset 0px -150px 100px -100px var(--fairy) , 0px 0px 0px 0px transparent !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pokemon-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
  overflow-x: auto;
 | 
			
		||||
  overflow-y: hidden;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 220px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pokemon-card {
 | 
			
		||||
  height: 200px;
 | 
			
		||||
  min-width: 300px;
 | 
			
		||||
  background-color: #444;
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
  border-radius: 40px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pokemon-card img {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  top: -120px;
 | 
			
		||||
  left: 100px;
 | 
			
		||||
  height: 192px;
 | 
			
		||||
  width: 192px;
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
  image-rendering: pixelated;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pokemon-card .pokemon-name {
 | 
			
		||||
  font-weight: 500;
 | 
			
		||||
  font-size: 1.15em;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  top: 15px;
 | 
			
		||||
  left: 15px;
 | 
			
		||||
  z-index: 1;
 | 
			
		||||
  text-shadow: black 1px 1px 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pokemon-card .pokemon-id {
 | 
			
		||||
  font-weight: 100;
 | 
			
		||||
  font-size: 3.5em;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  top: 15px;
 | 
			
		||||
  left: 15px;
 | 
			
		||||
  z-index: 0;
 | 
			
		||||
  text-shadow: #0008 1px 1px 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* CAROUSEL STYLES */
 | 
			
		||||
 | 
			
		||||
#carousel {
 | 
			
		||||
| 
						 | 
				
			
			@ -344,4 +713,10 @@ h3 {
 | 
			
		|||
    grid-row: 3 / 3;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* POKEDEX STYLES */
 | 
			
		||||
 | 
			
		||||
  #generation-selector {
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,13 @@
 | 
			
		|||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div id="below-landing">
 | 
			
		||||
        <section id="pokedex">
 | 
			
		||||
          <h2>Pokedex</h2>
 | 
			
		||||
          <form id="generation-selector"></form>
 | 
			
		||||
          <div id="pokemon-container"></div>
 | 
			
		||||
          <div id="type-selector"></div>            
 | 
			
		||||
        </section>
 | 
			
		||||
 | 
			
		||||
        <section id="features-intro" class="content-column features">
 | 
			
		||||
          <h2>Features</h2>
 | 
			
		||||
          <p>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										230
									
								
								js/scripts.js
								
								
								
								
							
							
						
						
									
										230
									
								
								js/scripts.js
								
								
								
								
							| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
console.log("hello");
 | 
			
		||||
let controller = new AbortController(); // Reference[1] https://levelup.gitconnected.com/asynchronous-tasks-got-you-down-heres-how-to-cancel-them-480801e69ae5
 | 
			
		||||
let signal = controller.signal;
 | 
			
		||||
 | 
			
		||||
// COLOUR PICKER BACKGROUND
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -175,6 +176,227 @@ function transitionLake() {
 | 
			
		|||
    transitionBackground("assets/photos/hintersee-3601004.jpg", "white");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// POKEDEX
 | 
			
		||||
 | 
			
		||||
async function initPokedex() {
 | 
			
		||||
    await populateGenerations();
 | 
			
		||||
    await populateTypes();
 | 
			
		||||
    populatePokedex(signal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function populateGenerations() {
 | 
			
		||||
    const container = document.getElementById("generation-selector");
 | 
			
		||||
    const url = "https://pokeapi.co/api/v2/generation/";
 | 
			
		||||
    const response = await fetch(url);
 | 
			
		||||
    const data = await response.json();
 | 
			
		||||
 | 
			
		||||
    let generations = [];
 | 
			
		||||
    let generationsURL = [];
 | 
			
		||||
    
 | 
			
		||||
    const genArray = data.results;
 | 
			
		||||
    for (let i = 0; i < genArray.length; i++) {
 | 
			
		||||
        const gen = genArray[i];
 | 
			
		||||
        const genName = gen.name;
 | 
			
		||||
        const genId = genName.split("-")[1].toUpperCase();
 | 
			
		||||
        generations.push(genId);
 | 
			
		||||
        generationsURL.push(gen.url);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    for (let i = 0; i < generations.length; i++) {
 | 
			
		||||
        const gen = generations[i];
 | 
			
		||||
        const genButton = document.createElement("input");
 | 
			
		||||
        genButton.type = "checkbox";
 | 
			
		||||
        genButton.value = generationsURL[i];
 | 
			
		||||
        genButton.id = `gen${gen}`;
 | 
			
		||||
        genButton.checked = true;
 | 
			
		||||
        container.appendChild(genButton);
 | 
			
		||||
        const genLabel = document.createElement("label");
 | 
			
		||||
        genLabel.htmlFor = `gen${gen}`;
 | 
			
		||||
        genLabel.innerHTML = `${gen}`;
 | 
			
		||||
        container.appendChild(genLabel);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getSelectedGenerations() {
 | 
			
		||||
    const container = document.getElementById("generation-selector");
 | 
			
		||||
    const checkboxes = container.getElementsByTagName("input");
 | 
			
		||||
    let selected = [];
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < checkboxes.length; i++) {
 | 
			
		||||
        if (checkboxes[i].checked) {
 | 
			
		||||
            selected.push(checkboxes[i].value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return(selected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function populateTypes() {
 | 
			
		||||
    const container = document.getElementById("type-selector");
 | 
			
		||||
    const url = "https://pokeapi.co/api/v2/type";
 | 
			
		||||
    const response = await fetch(url);
 | 
			
		||||
    const data = await response.json();
 | 
			
		||||
 | 
			
		||||
    let types = [];
 | 
			
		||||
    
 | 
			
		||||
    const typeArray = data.results;
 | 
			
		||||
    for (let i = 0; i < typeArray.length; i++) {
 | 
			
		||||
        const type = typeArray[i];
 | 
			
		||||
        const typeResponse = await fetch(type.url);
 | 
			
		||||
        const typeData = await typeResponse.json();
 | 
			
		||||
        if (typeData.id < 1000) {
 | 
			
		||||
            types.push(type.name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    for (let i = 0; i < types.length; i++) {
 | 
			
		||||
        const type = types[i];
 | 
			
		||||
        const typeButton = document.createElement("input");
 | 
			
		||||
        typeButton.type = "checkbox";
 | 
			
		||||
        typeButton.value = type;
 | 
			
		||||
        typeButton.id = type;
 | 
			
		||||
        typeButton.checked = true;
 | 
			
		||||
        container.appendChild(typeButton);
 | 
			
		||||
 | 
			
		||||
        const typeImg = document.createElement("img");
 | 
			
		||||
        typeImg.src = `https://raw.githubusercontent.com/duiker101/pokemon-type-svg-icons/5781623f147f1bf850f426cfe1874ba56a9b75ee/icons/${type}.svg`;
 | 
			
		||||
        typeImg.alt = `${type}`;
 | 
			
		||||
 | 
			
		||||
        const typeLabel = document.createElement("label");
 | 
			
		||||
        typeLabel.htmlFor = type;
 | 
			
		||||
        typeLabel.appendChild(typeImg);
 | 
			
		||||
        container.appendChild(typeLabel);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getSelectedTypes() {
 | 
			
		||||
    const container = document.getElementById("type-selector");
 | 
			
		||||
    const checkboxes = container.getElementsByTagName("input");
 | 
			
		||||
    let selected = [];
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < checkboxes.length; i++) {
 | 
			
		||||
        if (checkboxes[i].checked) {
 | 
			
		||||
            selected.push(checkboxes[i].value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return selected;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function populatePokedex(signal) {
 | 
			
		||||
    const container = document.getElementById("pokemon-container");
 | 
			
		||||
    container.innerHTML = "";
 | 
			
		||||
    const types = await getSelectedTypes();
 | 
			
		||||
    const generations = await getSelectedGenerations();
 | 
			
		||||
    for (let i = 0; i < generations.length; i++) {
 | 
			
		||||
        if (signal.aborted) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const url = generations[i];
 | 
			
		||||
        const response = await fetch(url);
 | 
			
		||||
        const data = await response.json();
 | 
			
		||||
        const pokemon = data.pokemon_species;
 | 
			
		||||
        for (let j = 0; j < pokemon.length; j++) {
 | 
			
		||||
            if (signal.aborted) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            const poke = pokemon[j];
 | 
			
		||||
            const speciesURL = poke.url;
 | 
			
		||||
            const speciesResponse = await fetch(speciesURL);
 | 
			
		||||
            const speciesData = await speciesResponse.json();
 | 
			
		||||
            const varieties = speciesData.varieties;
 | 
			
		||||
            for (let k = 0; k < varieties.length; k++) {
 | 
			
		||||
                if (signal.aborted) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                const variety = varieties[k];
 | 
			
		||||
                const varietyURL = variety.pokemon.url;
 | 
			
		||||
                const varietyResponse = await fetch(varietyURL);
 | 
			
		||||
                const varietyData = await varietyResponse.json();
 | 
			
		||||
                const varietyTypes = varietyData.types;
 | 
			
		||||
                if (types.includes(varietyTypes[0].type.name)) {
 | 
			
		||||
                    if (signal.aborted) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    addPokemon(varietyData);
 | 
			
		||||
                } else {
 | 
			
		||||
                    try {
 | 
			
		||||
                        if (types.includes(varietyTypes[1].type.name)) {
 | 
			
		||||
                            if (signal.aborted) {
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                            addPokemon(varietyData);
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch {
 | 
			
		||||
                        //no second type
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addPokemon(pokemonData) {
 | 
			
		||||
    const container = document.getElementById("pokemon-container");
 | 
			
		||||
 | 
			
		||||
    // if (container.childElementCount > 100) {
 | 
			
		||||
    //     return;
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    const pokemon = document.createElement("div");
 | 
			
		||||
    pokemon.className = "pokemon-card";
 | 
			
		||||
    pokemon.classList.add(pokemonData.types[0].type.name + "-primary-type");
 | 
			
		||||
    if (pokemonData.types[1]) {
 | 
			
		||||
        pokemon.classList.add(pokemonData.types[1].type.name + "-secondary-type");
 | 
			
		||||
    }
 | 
			
		||||
    pokemon.id = pokemonData.name;
 | 
			
		||||
 | 
			
		||||
    const pokemonName = document.createElement("p");
 | 
			
		||||
    pokemonName.className = "pokemon-name";
 | 
			
		||||
    let formatedName = "";
 | 
			
		||||
    pokemonData.name.split("-").forEach((word) => { 
 | 
			
		||||
        formatedName += word.charAt(0).toUpperCase() + word.slice(1) + " ";
 | 
			
		||||
    });
 | 
			
		||||
    if (formatedName.length > 20) {
 | 
			
		||||
        formatedName = formatedName.slice(0, formatedName.length - 1);
 | 
			
		||||
        formatedName = formatedName.slice(0, formatedName.lastIndexOf(" "));
 | 
			
		||||
    }
 | 
			
		||||
    pokemonName.innerHTML = formatedName;
 | 
			
		||||
    pokemon.appendChild(pokemonName);
 | 
			
		||||
 | 
			
		||||
    const pokemonId = document.createElement("p");
 | 
			
		||||
    pokemonId.className = "pokemon-id";
 | 
			
		||||
    pokemonId.innerHTML = `#${pokemonData.id}`;
 | 
			
		||||
    pokemon.style.order = pokemonData.id;
 | 
			
		||||
    pokemon.appendChild(pokemonId);
 | 
			
		||||
 | 
			
		||||
    const pokemonImg = document.createElement("img");
 | 
			
		||||
    pokemonImg.src = pokemonData.sprites.front_default;
 | 
			
		||||
    pokemonImg.alt = pokemonData.name;
 | 
			
		||||
    pokemon.appendChild(pokemonImg);
 | 
			
		||||
 | 
			
		||||
    container.appendChild(pokemon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const generationSelector = document.getElementById("generation-selector");
 | 
			
		||||
generationSelector.addEventListener("change", (event) => {
 | 
			
		||||
    restartPokedexUpdate();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const typeSelector = document.getElementById("type-selector");
 | 
			
		||||
typeSelector.addEventListener("change", (event) => {
 | 
			
		||||
    restartPokedexUpdate();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function restartPokedexUpdate() {
 | 
			
		||||
    controller.abort();
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
        controller = new AbortController();
 | 
			
		||||
        signal = controller.signal;
 | 
			
		||||
        populatePokedex(signal);
 | 
			
		||||
    }, 250);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ACCORDIAN IMAGES
 | 
			
		||||
 | 
			
		||||
function carouselExpand(i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +428,7 @@ function initCarousel() {
 | 
			
		|||
// INITIALIZATION
 | 
			
		||||
// Set background colour to last saved value
 | 
			
		||||
const bgColor = document.getElementById("bgColour");
 | 
			
		||||
bgColor.value = localStorage.getItem("bgColour") || "#ffffff";
 | 
			
		||||
bgColor.value = localStorage.getItem("bgColour") || "#ff0070";
 | 
			
		||||
const initR = parseInt(bgColour.value.substring(1, 3), 16);
 | 
			
		||||
const initG = parseInt(bgColour.value.substring(3, 5), 16);
 | 
			
		||||
const initB = parseInt(bgColour.value.substring(5, 7), 16);
 | 
			
		||||
| 
						 | 
				
			
			@ -214,4 +436,6 @@ changeBackground(initR, initG, initB);
 | 
			
		|||
document.documentElement.style.setProperty("--bgColor", bgColour.value);
 | 
			
		||||
// Initialize carousel
 | 
			
		||||
initCarousel();
 | 
			
		||||
carouselExpand(1);
 | 
			
		||||
carouselExpand(1);
 | 
			
		||||
// Initialize pokedex
 | 
			
		||||
initPokedex();
 | 
			
		||||
		Loading…
	
		Reference in New Issue