FEWD-CTEC3905/js/scripts.js

441 lines
13 KiB
JavaScript

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
function changeBackground(R, G, B) {
const colours = [
[255, 255, 255],
[210, 100, 110],
[90, 65, 125],
[210, 160, 100],
[220, 100, 15],
[210, 15, 0],
[100, 125, 150],
[100, 140, 90],
[20, 40, 20],
[220, 140, 180],
[0, 0, 0],
[0, 140, 220],
[0, 255, 160],
[60, 90, 20]
]
let closestDistance = 500;
let closest = 0;
for (let i = 0; i < colours.length; i++) {
distance = Math.abs(R - colours[i][0]) +
Math.abs(G - colours[i][1]) +
Math.abs(B - colours[i][2]);
if (distance < closestDistance) {
closestDistance = distance;
closest = i;
}
}
switch (closest) {
case 0:
transitionFog();
break;
case 1:
transitionSunset();
break;
case 2:
transitionSunsetPurple();
break;
case 3:
transitionSunsetYellow();
break;
case 4:
transitionRoadOrange();
break;
case 5:
transitionRoadRed();
break;
case 6:
transitionClouds();
break;
case 7:
transitionForest();
break;
case 8:
transitionAvenue();
break;
case 9:
transitionMountain();
break;
case 10:
transitionGalaxy();
break;
case 11:
transitionThunderstorm();
break;
case 12:
transitionAurora();
break;
case 13:
transitionLake();
break;
default:
transitionFog();
break;
}
}
bgColour.addEventListener("input", () => {
const R = parseInt(bgColour.value.substring(1, 3), 16);
const G = parseInt(bgColour.value.substring(3, 5), 16);
const B = parseInt(bgColour.value.substring(5, 7), 16);
changeBackground(R, G, B);
localStorage.setItem("bgColour", bgColour.value);
document.documentElement.style.setProperty("--bgColor", bgColour.value);
});
function transitionBackground(newUrl, blackwhite) {
const background = document.getElementById("background");
const transitionLayer = document.getElementById("background-transition");
const title = document.getElementById("titleBanner");
transitionLayer.removeEventListener("transitionend", () => {});
title.className = blackwhite;
transitionLayer.style.background = `url(${newUrl}) 50% 50% / cover`;
transitionLayer.style.display = "block";
transitionLayer.style.opacity = "0";
setTimeout(() => {
transitionLayer.style.opacity = '0';
}, 10);
setTimeout(() => {
transitionLayer.style.opacity = '1';
}, 10);
transitionLayer.addEventListener("transitionend", () => {
background.style.background = `url(${newUrl}) 50% 50% / cover`;
transitionLayer.style.display = "none";
transitionLayer.style.opacity = "0";
}, {once: true});
}
function transitionFog() {
transitionBackground("assets/photos/fog-8519076-nordseher.jpg", "black");
}
function transitionSunset() {
transitionBackground("assets/photos/sunset-5928907-lizzymay.jpg", "white");
}
function transitionSunsetPurple() {
transitionBackground("assets/photos/sunset-1373171.jpg", "black");
}
function transitionSunsetYellow() {
transitionBackground("assets/photos/sunset-404072.jpg", "black");
}
function transitionRoadOrange() {
transitionBackground("assets/photos/road-1072821.jpg", "white");
}
function transitionRoadRed() {
transitionBackground("assets/photos/road-8395119.jpg", "white");
}
function transitionClouds() {
transitionBackground("assets/photos/clouds-8459053.jpg", "black");
}
function transitionForest() {
transitionBackground("assets/photos/forest-3622519.jpg", "black");
}
function transitionAvenue() {
transitionBackground("assets/photos/avenue-815297.jpg", "black");
}
function transitionMountain() {
transitionBackground("assets/photos/mountain-landscape-2031539.jpg", "black");
}
function transitionGalaxy() {
transitionBackground("assets/photos/milky-way-1845068.jpg", "white");
}
function transitionThunderstorm() {
transitionBackground("assets/photos/thunderstorm-3625405.jpg", "black");
}
function transitionAurora() {
transitionBackground("assets/photos/aurora-1197753.jpg", "black");
}
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) {
const carousel = document.getElementById(`carousel-container`);
const carouselItems = carousel.getElementsByClassName("carousel-item");
i = i - 1;
if (i < carouselItems.length) {
for (let j = 0; j < carouselItems.length; j++) {
carouselItems[j].className = "carousel-item";
}
carouselItems[i].className = "carousel-item active";
}
}
function initCarousel() {
const carousel = document.getElementById(`carousel-container`);
const carouselItems = carousel.getElementsByClassName("carousel-item");
for (let i = 0; i < carouselItems.length; i++) {
carouselItems[i].addEventListener("mouseover", () => {
carouselExpand(i + 1);
});
}
}
// INITIALIZATION
// Set background colour to last saved value
const bgColor = document.getElementById("bgColour");
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);
changeBackground(initR, initG, initB);
document.documentElement.style.setProperty("--bgColor", bgColour.value);
// Initialize carousel
initCarousel();
carouselExpand(1);
// Initialize pokedex
initPokedex();