diff --git a/css/styles.css b/css/styles.css index 521cb6c..f859dd5 100644 --- a/css/styles.css +++ b/css/styles.css @@ -259,6 +259,20 @@ h3 { width: 100%; } +#description-carousel { + display: flex; + flex-direction: row; + margin: 10px; + background: #222; + border-radius: 15px; + padding-left: 28px; + padding-right: 28px; +} + +.description-carousel-item { + color: white; +} + @keyframes transform { from { background-position: 0px 0px; @@ -901,6 +915,12 @@ h3 { font-size: 2em; } + #pokemon-contents { + display: grid; + grid-template-columns: 475px 1fr; + grid-column-gap: 8px; + } + #pokemon-display .pokemon-name { font-size: 2.2em; text-align: left; @@ -938,6 +958,60 @@ h3 { grid-row: 2; } + #description-carousel { + margin: 0; + overflow: hidden; + height: fit-content; + position: relative; + } + + #description-carousel .description-carousel-item { + width: 100%; + flex: 0 0 100%; + height: fit-content; + margin-right: 33px; + transition: transform 0.3s ease; + } + + #description-carousel #carousel-left-button { + top: 0; + left: 0; + text-align: left; + } + + #description-carousel #carousel-right-button { + top: 0; + right: 0; + text-align: right; + } + + #description-carousel button { + position: absolute; + height: 100%; + border: none; + background: #0000; + color: white; + width: 30px; + cursor: pointer; + } + + #description-carousel button:hover { + font-size: 16px; + } + + #description-carousel .description-text { + left: 0; + color: #ccc; + } + + #description-carousel .description-game { + left: 0; + font-size: 1em; + font-weight: 400; + padding-bottom: 10px; + border-bottom: 1px solid #ccc; + } + /* BELOW LANDING STYLES */ #below-landing { diff --git a/js/scripts.js b/js/scripts.js index f402600..66165af 100644 --- a/js/scripts.js +++ b/js/scripts.js @@ -1,5 +1,6 @@ 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; +let activePokemonCarousel = 0; // COLOUR PICKER BACKGROUND @@ -403,6 +404,7 @@ function restartPokedexUpdate() { } async function createPokemonDisplay(id) { + activePokemonCarousel = 0; const fullscreenContainer = document.getElementById("fullscreen"); fullscreenContainer.className = "visible"; @@ -425,6 +427,10 @@ async function createPokemonDisplay(id) { const url = `https://pokeapi.co/api/v2/pokemon/${id}`; const response = await fetch(url); const data = await response.json(); + + const speciesurl = data.species.url; + const speciesResponse = await fetch(speciesurl); + const speciesData = await speciesResponse.json(); pokemonDisplay.className = data.types[0].type.name + "-primary-type" @@ -500,9 +506,87 @@ async function createPokemonDisplay(id) { imageAndStats.appendChild(pokemonImgContainer); imageAndStats.appendChild(pokemonStatblock); + const descriptionCarousel = document.createElement("div"); + descriptionCarousel.id = "description-carousel"; + + let descriptionArray = []; + + speciesData.flavor_text_entries.forEach((entry) => { + if (entry.language.name === "en") { + const game = entry.version.name; + const pokemonDescription = entry.flavor_text; + descriptionArray[game] = pokemonDescription; + } + }); + + let descriptionArrayFiltered = [] + let gameArrayFiltered = [] + + for (const game in descriptionArray) { + let index = descriptionArrayFiltered.indexOf(descriptionArray[game]); + if (index === -1) { + descriptionArrayFiltered.push(descriptionArray[game]); + gameArrayFiltered.push(game); + } else { + gameArrayFiltered[index] += " | " + game; + } + } + + descriptionArrayFiltered.forEach((description, i) => { + const carouselItem = document.createElement("div"); + carouselItem.className = "description-carousel-item"; + + let descriptionFormatted = description; + descriptionFormatted = descriptionFormatted.replace("\u000c", " "); + descriptionFormatted = descriptionFormatted.replace("\n", " "); + + const descriptionText = document.createElement("p"); + descriptionText.className = "description-text"; + descriptionText.innerHTML = descriptionFormatted; + + const descriptionGame = document.createElement("p"); + descriptionGame.className = "description-game"; + descriptionGame.innerHTML = gameArrayFiltered[i].toUpperCase(); + + carouselItem.appendChild(descriptionGame); + carouselItem.appendChild(descriptionText); + descriptionCarousel.appendChild(carouselItem); + }); + + const leftButton = document.createElement("button"); + leftButton.id = "carousel-left-button"; + leftButton.innerHTML = "◀ "; + leftButton.style.display = "none"; + + const rightButton = document.createElement("button"); + rightButton.id = "carousel-right-button"; + rightButton.innerHTML = " ▶"; + + leftButton.addEventListener("click", () => { + pokemonCarousel("left"); + }); + + rightButton.addEventListener("click", () => { + pokemonCarousel("right"); + }); + + descriptionCarousel.appendChild(leftButton); + descriptionCarousel.appendChild(rightButton); + + window.addEventListener("resize", () => { + transitionPokemonCarousel(activePokemonCarousel); + }); + + const pokemonContents = document.createElement("div"); + pokemonContents.id = "pokemon-contents"; + pokemonDisplay.appendChild(pokemonName); pokemonDisplay.appendChild(pokemonId); - pokemonDisplay.appendChild(imageAndStats); + + pokemonContents.appendChild(imageAndStats); + pokemonContents.appendChild(descriptionCarousel); + + pokemonDisplay.appendChild(pokemonContents); fullscreenContainer.appendChild(pokemonDisplay); fullscreenContainer.appendChild(closeButton); @@ -518,6 +602,55 @@ function closePokemonDisplay() { } +function pokemonCarousel(direction) { + const items = document.getElementsByClassName("description-carousel-item").length; + const leftButton = document.getElementById("carousel-left-button"); + const rightButton = document.getElementById("carousel-right-button"); + + if (items < 2) { + console.log("Not enough items for a carousel"); + return; + } + + if (direction === "left" && activePokemonCarousel === 0) { + console.log("Carousel already too far left"); + return; + } else if (direction === "right" && activePokemonCarousel === items - 1) { + console.log("Carousel already too far right"); + return; + } + + if (direction == "left") { + activePokemonCarousel--; + } else if (direction == "right") { + activePokemonCarousel++; + } + + if (activePokemonCarousel == 0) { + leftButton.style.display = "none"; + } else { + leftButton.style.display = "block"; + } + + if (activePokemonCarousel == items - 1) { + rightButton.style.display = "none"; + } else { + rightButton.style.display = "block"; + } + + transitionPokemonCarousel(activePokemonCarousel); +} + +function transitionPokemonCarousel(i) { + let offset = 0; + const items = document.getElementsByClassName("description-carousel-item"); + const width = items[0].offsetWidth; + offset = (i * (width + 33)); + for (const item of items) { + item.style.transform = `translateX(-${offset}px)`; + } +} + // ACCORDIAN IMAGES function carouselExpand(i) { @@ -559,19 +692,4 @@ document.documentElement.style.setProperty("--bgColor", bgColour.value); initCarousel(); carouselExpand(1); // Initialize pokedex -initPokedex(); - -function handleMouseMove(event) { - const width = document.body.clientWidth; - const height = document.body.clientHeight; - - const xAbsolute = event.clientX / width; - const yAbsolute = event.clientY / height; - - const maxOffset = 40; - const xOffset = (xAbsolute * (2 * maxOffset)) - maxOffset; - const yOffset = (yAbsolute * (2 * maxOffset)) - maxOffset; - - document.body.style.backgroundPosition = `${xOffset}px ${yOffset}px`; - } - +initPokedex(); \ No newline at end of file