diff --git a/css/styles.css b/css/styles.css index ba7eb2c..3d5790c 100644 --- a/css/styles.css +++ b/css/styles.css @@ -221,10 +221,7 @@ h3 { padding: 10px; overflow-y: scroll; min-width: 260px; -} - -#pokemon-display::-webkit-scrollbar { - display: none; + position: relative; } #fullscreen #close-button { @@ -241,6 +238,20 @@ h3 { text-shadow: black 1px 1px 3px; } +#pokemon-display #type-container { + position: absolute; + top: 0; + right: 0; + margin-top: 8px; + margin-right: 10px; +} + +#pokemon-display .type-icon { + width: 40px; + height: 40px; + margin-left: 10px; +} + #pokemon-display #image-container { display: flex; justify-content: center; @@ -255,6 +266,12 @@ h3 { margin-bottom: 8px; } +#pokemon-display #dex-and-type-container { + display: flex; + flex-direction: column; + width: 100%; +} + #pokemon-display img { width: 100%; } @@ -267,9 +284,11 @@ h3 { padding-left: 28px; padding-right: 28px; margin: 0; + margin-bottom: 8px; overflow: hidden; height: fit-content; position: relative; + overflow-y: scroll; } #description-carousel .description-carousel-item { @@ -310,11 +329,13 @@ h3 { #description-carousel .description-text { left: 0; color: #ccc; + font-style: italic; + font-weight: 250; } #description-carousel .description-game { left: 0; - font-size: 1em; + font-size: 1.2em; font-weight: 400; padding-bottom: 10px; border-bottom: 1px solid #ccc; @@ -335,7 +356,7 @@ h3 { margin: 0; margin-left: 10px; margin-bottom: 10px; - text-align: center; + text-align: left; } #pokemon-display .pokemon-id { @@ -421,6 +442,64 @@ h3 { margin-bottom: 8px; } +#type-chart-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr 1fr; + width: 100%; + grid-template-rows: 60px 1fr; + background-color: #222; + border-radius: 15px; + color: #ccc; + margin-bottom: 8px; + height: fit-content; +} + +#type-chart-container #type-chart-title { + grid-column: 1 / span 5; + margin: 0; + margin-top: 10px; + margin-left: 10px; + color: white; + font-weight: 400; + text-align: center; + padding-bottom: 5px; + border-bottom: 1px solid #ccc; + font-size: 1.2em; +} + +.type-chart-title { + display: flex; + flex-direction: column; + text-align: center; + height: 40px; + border-bottom: 1px solid #ccc; + justify-content: center; + padding: 2px; +} + +.type-chart-element { + display: flex; + flex-direction: column; + justify-content: center; + color: black; + text-align: center; + margin: 2px; + height: 18px; + border-radius: 9px; +} + +#noeffect-column, #doubleresist-column, #resist-column, #weak-column { + border-right: 1px solid #ccc; +} + +#type-chart-container .type-chart-column { + display: flex; + flex-direction: column; + font-size: 0.6em; + padding: 0; + list-style-type: none; +} + /* POKEDEX STYLES */ #pokedex { @@ -738,6 +817,7 @@ h3 { margin: 10px; border-radius: 40px; overflow: hidden; + cursor: pointer; } .pokemon-card img { @@ -868,13 +948,18 @@ h3 { padding: 20px; max-height: 600px; max-width: 900px; + padding-bottom: 12px; } #image-and-stats { width: 100%; display: grid; grid-template-columns: 1fr 280px; + } + #pokemon-display #type-container { + margin-top: 14px; + margin-right: 20px; } #pokemon-display img { @@ -953,6 +1038,7 @@ h3 { padding: 20px; max-height: 755px; max-width: 1120px; + overflow: hidden; } #fullscreen #close-button { @@ -967,6 +1053,7 @@ h3 { display: grid; grid-template-columns: 475px 1fr; grid-column-gap: 8px; + grid-template-rows: auto; } #pokemon-display .pokemon-name { @@ -980,6 +1067,24 @@ h3 { font-size: 2.5em; } + #pokemon-display #type-container { + margin-top: 15px; + margin-right: 25px; + } + + #pokemon-display .type-icon { + width: 60px; + height: 60px; + } + + #image-and-stats { + width: 475px; + display: flex; + flex-direction: column; + grid-column: 1; + grid-row: 1 / span 2; + } + #pokemon-display img { max-height: 475px; max-width: 475px; @@ -1006,6 +1111,15 @@ h3 { grid-row: 2; } + #description-carousel { + grid-column: 2; + height: 338px; + } + + #type-chart-container { + height: 337px; + } + /* BELOW LANDING STYLES */ #below-landing { diff --git a/index.html b/index.html index 8cd3f26..c09f70c 100644 --- a/index.html +++ b/index.html @@ -23,7 +23,8 @@

Pokedex

-
+
+

Select any creature to view its profile. You can use the top buttons to toggle creatures from different generations or use the bottom buttons to toggle creatures with a specific type.

diff --git a/js/scripts.js b/js/scripts.js index 66165af..40c4e36 100644 --- a/js/scripts.js +++ b/js/scripts.js @@ -209,7 +209,11 @@ async function populateGenerations() { genButton.type = "checkbox"; genButton.value = generationsURL[i]; genButton.id = `gen${gen}`; - genButton.checked = true; + if (gen === "I") { + genButton.checked = true; + } else { + genButton.checked = false; + } container.appendChild(genButton); const genLabel = document.createElement("label"); genLabel.htmlFor = `gen${gen}`; @@ -256,7 +260,11 @@ async function populateTypes() { typeButton.type = "checkbox"; typeButton.value = type; typeButton.id = type; - typeButton.checked = true; + if (type === "normal") { + typeButton.checked = true; + } else { + typeButton.checked = false; + } container.appendChild(typeButton); const typeImg = document.createElement("img"); @@ -539,6 +547,7 @@ async function createPokemonDisplay(id) { let descriptionFormatted = description; descriptionFormatted = descriptionFormatted.replace("\u000c", " "); descriptionFormatted = descriptionFormatted.replace("\n", " "); + descriptionFormatted = descriptionFormatted.replace("POKéMON", "Pokémon"); const descriptionText = document.createElement("p"); descriptionText.className = "description-text"; @@ -570,6 +579,82 @@ async function createPokemonDisplay(id) { pokemonCarousel("right"); }); + const types = data.types; + const primaryType = types[0].type.name; + const primaryIcon = `https://raw.githubusercontent.com/duiker101/pokemon-type-svg-icons/5781623f147f1bf850f426cfe1874ba56a9b75ee/icons/${primaryType}.svg` + let secondaryType = ""; + + if (types[1]) { + secondaryType = types[1].type.name; + secondaryIcon = `https://raw.githubusercontent.com/duiker101/pokemon-type-svg-icons/5781623f147f1bf850f426cfe1874ba56a9b75ee/icons/${secondaryType}.svg` + } else { + secondaryType = "Monotype"; + } + + const typeChartContainer = document.createElement("div"); + typeChartContainer.id = "type-chart-container"; + + const typeChartTitle = document.createElement("p"); + typeChartTitle.id = "type-chart-title"; + typeChartTitle.innerHTML = "Type Chart"; + + const noeffectColumn = document.createElement("ul"); + noeffectColumn.id = "noeffect-column"; + noeffectColumn.className = "type-chart-column"; + const noeffectTitle = document.createElement("li"); + noeffectTitle.innerHTML = "Immune"; + noeffectTitle.className = "type-chart-title"; + noeffectColumn.appendChild(noeffectTitle); + + const doubleresistColumn = document.createElement("ul"); + doubleresistColumn.id = "doubleresist-column"; + doubleresistColumn.className = "type-chart-column"; + const doubleresistTitle = document.createElement("li"); + doubleresistTitle.innerHTML = "Double Resist"; + doubleresistTitle.className = "type-chart-title"; + doubleresistColumn.appendChild(doubleresistTitle); + + const resistColumn = document.createElement("ul"); + resistColumn.id = "resist-column"; + resistColumn.className = "type-chart-column"; + const resistTitle = document.createElement("li"); + resistTitle.innerHTML = "Resist"; + resistTitle.className = "type-chart-title"; + resistColumn.appendChild(resistTitle); + + const weakColumn = document.createElement("ul"); + weakColumn.id = "weak-column"; + weakColumn.className = "type-chart-column"; + const weakTitle = document.createElement("li"); + weakTitle.innerHTML = "Weak"; + weakTitle.className = "type-chart-title"; + weakColumn.appendChild(weakTitle); + + const doubleweakColumn = document.createElement("ul"); + doubleweakColumn.id = "doubleweak-column"; + doubleweakColumn.className = "type-chart-column"; + const doubleweakTitle = document.createElement("li"); + doubleweakTitle.innerHTML = "Double Weak"; + doubleweakTitle.className = "type-chart-title"; + doubleweakColumn.appendChild(doubleweakTitle); + + typeChartContainer.appendChild(typeChartTitle); + typeChartContainer.appendChild(noeffectColumn); + typeChartContainer.appendChild(doubleresistColumn); + typeChartContainer.appendChild(resistColumn); + typeChartContainer.appendChild(weakColumn); + typeChartContainer.appendChild(doubleweakColumn); + + const primaryImg = document.createElement("img"); + primaryImg.src = primaryIcon; + primaryImg.alt = primaryType; + primaryImg.className = "type-icon"; + + const secondaryImg = document.createElement("img"); + secondaryImg.src = secondaryIcon; + secondaryImg.alt = secondaryType; + secondaryImg.className = "type-icon"; + descriptionCarousel.appendChild(leftButton); descriptionCarousel.appendChild(rightButton); @@ -580,16 +665,33 @@ async function createPokemonDisplay(id) { const pokemonContents = document.createElement("div"); pokemonContents.id = "pokemon-contents"; + const typeContainer = document.createElement("div"); + typeContainer.id = "type-container"; + typeContainer.appendChild(primaryImg); + typeContainer.appendChild(secondaryImg); + + // const dexAndTypeContainer = document.createElement("div"); + // dexAndTypeContainer.id = "dex-and-type-container"; + // dexAndTypeContainer.appendChild(descriptionCarousel); + // dexAndTypeContainer.appendChild(typeChartContainer); + pokemonDisplay.appendChild(pokemonName); pokemonDisplay.appendChild(pokemonId); + pokemonDisplay.appendChild(typeContainer); pokemonContents.appendChild(imageAndStats); + //pokemonContents.appendChild(dexAndTypeContainer); pokemonContents.appendChild(descriptionCarousel); + pokemonContents.appendChild(typeChartContainer); + pokemonDisplay.appendChild(pokemonContents); fullscreenContainer.appendChild(pokemonDisplay); fullscreenContainer.appendChild(closeButton); + + const typeChart = await calculateTypeChart(primaryType, secondaryType) + displayTypeChart(typeChart); } function closePokemonDisplay() { @@ -651,6 +753,120 @@ function transitionPokemonCarousel(i) { } } +async function calculateTypeChart(primaryType, secondaryType, stat) { + let typeArray = {"normal": 0, "fighting": 0, "flying": 0, "poison": 0, "ground": 0, "rock": 0, "bug": 0, "ghost": 0, "steel": 0, "fire": 0, "water": 0, "grass": 0, "electric": 0, "psychic": 0, "ice": 0, "dragon": 0, "dark": 0, "fairy": 0}; + + const primaryURL = `https://pokeapi.co/api/v2/type/${primaryType}`; + const primaryResponse = await fetch(primaryURL); + const primaryData = await primaryResponse.json(); + + primaryData.damage_relations.double_damage_from.forEach((type) => { + typeArray[type.name] += 1; + }); + primaryData.damage_relations.half_damage_from.forEach((type) => { + typeArray[type.name] -= 1; + }); + primaryData.damage_relations.no_damage_from.forEach((type) => { + typeArray[type.name] -= 999; + }); + + if (secondaryType !== "Monotype") { + const secondaryURL = `https://pokeapi.co/api/v2/type/${secondaryType}`; + const secondaryResponse = await fetch(secondaryURL); + const secondaryData = await secondaryResponse.json(); + + secondaryData.damage_relations.double_damage_from.forEach((type) => { + typeArray[type.name] += 1; + }); + secondaryData.damage_relations.half_damage_from.forEach((type) => { + typeArray[type.name] -= 1; + }); + secondaryData.damage_relations.no_damage_from.forEach((type) => { + typeArray[type.name] -= 999; + }); + } + + return typeArray; +} + +function displayTypeChart(typeArray) { + const resist = []; + const doubleresist = []; + const weak = []; + const doubleweak = []; + const noeffect = []; + for (const type in typeArray) { + if (typeArray[type] === -1) { + resist.push(type); + } else if (typeArray[type] === -2) { + doubleresist.push(type); + } else if (typeArray[type] === 1) { + weak.push(type); + } + else if (typeArray[type] === 2) { + doubleweak.push(type); + } else if (typeArray[type] < -100) { + noeffect.push(type); + } else { + //neutral + } + } + + const noeffectColumn = document.getElementById("noeffect-column"); + const doubleresistColumn = document.getElementById("doubleresist-column"); + const resistColumn = document.getElementById("resist-column"); + const weakColumn = document.getElementById("weak-column"); + const doubleweakColumn = document.getElementById("doubleweak-column"); + + for (const element of document.getElementsByClassName("type-chart-element")) { + element.remove(); + } + + try { + noeffect.forEach((type) => { + const typeElement = document.createElement("li"); + typeElement.innerHTML = type.toUpperCase(); + typeElement.className = "type-chart-element"; + typeElement.classList.add(type + "-primary-type"); + noeffectColumn.appendChild(typeElement); + }); + + doubleresist.forEach((type) => { + const typeElement = document.createElement("li"); + typeElement.innerHTML = type.toUpperCase(); + typeElement.className = "type-chart-element"; + typeElement.classList.add(type + "-primary-type"); + doubleresistColumn.appendChild(typeElement); + }); + + resist.forEach((type) => { + const typeElement = document.createElement("li"); + typeElement.innerHTML = type.toUpperCase(); + typeElement.className = "type-chart-element"; + typeElement.classList.add(type + "-primary-type"); + resistColumn.appendChild(typeElement); + }); + + weak.forEach((type) => { + const typeElement = document.createElement("li"); + typeElement.innerHTML = type.toUpperCase(); + typeElement.className = "type-chart-element"; + typeElement.classList.add(type + "-primary-type"); + weakColumn.appendChild(typeElement); + }); + + doubleweak.forEach((type) => { + const typeElement = document.createElement("li"); + typeElement.innerHTML = type.toUpperCase(); + typeElement.className = "type-chart-element"; + typeElement.classList.add(type + "-primary-type"); + doubleweakColumn.appendChild(typeElement); + }); + } catch { + //type elements not built yet + } +} + // ACCORDIAN IMAGES function carouselExpand(i) {