Pokédex

Opgave

Maak een Pokédex pagina die informatie toont over een Pokémon.

Pokedex

Hoe starten?

  1. Net als altijd in VS Code, begin je met het aanmaken van een directory (folder) om je project in te bundelen. Geef deze directory een toepasselijke naam, bijvoorbeeld Pokedex.
  2. Maak een index.html bestand aan. Gebruik de emmet snippet ! om je op weg te helpen.
  3. Maak een style.css bestand en link hiernaar door een link tag toe te voegen in de head van je index.html bestand.
index.html
<link rel="stylesheet" href="style.css">
  1. Laad Vue.js in je index.html bestand door een script tag toe te voegen in de head.
index.html
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  1. Maak een pokemon.js bestand aan met de code die je onder dit stappenplan vindt. Je hoeft deze code momenteel nog niet te begrijpen.
  2. Koppel dit pokemon.js bestand aan je index.html bestand door een script tag toe te voegen in de head.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script defer src="pokemon.js"></script>
    <link rel="stylesheet" href="style.css">
    <title>Pokédex</title>
</head>
  1. Voeg een div toe met een id vue in de body van je index.html bestand. Dit is de plek waar Vue.js zal werken.
index.html
<body>
    <div id="vue">
        <!-- Hier komt de Pokédex -->
    </div>
</body>
  1. Werk de bestanden index.html, style.css en eventueel pokemon.js verder aan om de opdrachten uit te voeren. Dankzij Vue.js zal je Pokédex dynamisch werken. Je kan dynamische data weergeven met behulp van de mustache syntax {{ }}.
index.html
<body>
    <div id="vue">
        <p> {{name}} is {{height}} m hoog.</p>
    </div>
</body>

Pokémon.js code

pokemon.js
let app = new Vue({
    el: '#vue',
    name: "Pokemon",
    data() {
        return {
            id: 104,
            pokemon: null,
            typeColours: {
                normal: '#A8A77A',
                fire: '#EE8130',
                water: '#6390F0',
                electric: '#F7D02C',
                grass: '#7AC74C',
                ice: '#96D9D6',
                fighting: '#C22E28',
                poison: '#A33EA1',
                ground: '#E2BF65',
                flying: '#A98FF3',
                psychic: '#F95587',
                bug: '#A6B91A',
                rock: '#B6A136',
                ghost: '#735797',
                dragon: '#6F35FC',
                dark: '#705746',
                steel: '#B7B7CE',
                fairy: '#D685AD',
            }
        }
    },
    computed: {
        name() {
            if (!this.pokemon) return
            const name = this.pokemon.name || 'Onbekend';
            return this.capitalize(name)
        },
        types() {
            return this.pokemon && this.pokemon.types.map(t => t.type.name)
        },
        type() {
            return this.pokemon && this.types[0] || 'Onbekend'
        },
        height() {
            if (!this.pokemon) return
            const dm = this.pokemon.height
            let str = (dm / 10).toString()
            str = str.replaceAll(".", ",");
            str = str + " m"
            return str
        },
        color() {
            return this.pokemon && this.pokemon.color.name || 'Onbekend'
        },
        spriteUrl() {
            return this.pokemon && this.pokemon.sprites.other.dream_world.front_default || ""
        },
        moves() {
            if (!this.pokemon) return
            let levelMoves = []
            let allMoves = this.pokemon.moves
            allMoves.forEach(move => {
                const moveFr = move.version_group_details.find(m => m.version_group.name == "firered-leafgreen")
                if (moveFr && moveFr.level_learned_at > 0) {
                    levelMoves.push({ level: moveFr.level_learned_at, name: move.move.name })
                }
            });
            // opgave: eerste 5 aanvallen weergeven
            if (levelMoves.length < 5) {
                for (let i = levelMoves.length; i < 5; i++) {
                    levelMoves.push({ level: 99, name: "Onbekend" })
                }
            }
            return levelMoves.sort((a, b) => a.level - b.level)
        },
        flavor() {
            if (!this.pokemon) return
            let flavor = this.pokemon.flavor_text_entries.find(fl => fl.version.name == "firered" && fl.language.name == "en")
            return flavor && flavor.flavor_text || "Geen info"
        },
        typeColor() {
            return this.typeColours[this.type] || '#777';
        }
    },
    methods: {
        async getPokemon(id) {
            id = Math.min(Math.max(1, id), 649)
            const url = `https://pokeapi.co/api/v2/pokemon/${id}`;
            const res = await fetch(url)
            const pokemon = res.ok && await res.json()
            const urlSpec = `https://pokeapi.co/api/v2/pokemon-species/${id}`;
            const resSpec = await fetch(urlSpec)
            const species = resSpec.ok && await resSpec.json()
            this.pokemon = Object.assign(pokemon, species);
            this.id = id;
        },
        capitalize(word) {
            return word && word[0].toUpperCase() + word.slice(1);
        },
        next() {
            this.id++;
            this.getPokemon(this.id);
        },
        prev() {
            this.id--;
            this.getPokemon(this.id);
        },
        getTypeColor(type){
            return this.typeColours[type] || '#777'
        }
    },
    mounted() {
        this.getPokemon(this.id)
    }
})

Opdrachten

Basis

  1. Geef je website de titel ‘Pokédex’. Zorg dat deze titel zowel in de browser als titel van het tabblad verschijnt, als bovenaan de pagina.
  2. Geef je website een lichtgrijze achtergrond.
  3. Zorg ervoor dat de titel een lettergrootte van 32pt heeft en vetgedrukt staat.
  4. Maak een ondertitel met de naam van de Pokémon en zijn nationale Pokédex nummer.
  5. Plaats een afbeelding van de Pokémon. Geef deze een vaste breedte van 250 pixels. Noot: werk met een : voor src om aan te geven dat de inhoud van spriteUrl dynamisch is, i.e. <img :src="spriteUrl">
  6. Om te vermijden dat de website telkens verspringt bij afbeeldingen van verschillende hoogte plaats je de afbeelding uit puntje 7 in een container met een vaste hoogte van 400px. Emmet tip: .container
index.html
<div class="container">
    <img :src="spriteUrl">
</div>
  1. Geef het type van de Pokémon weer in een badge met een achtergrondkleur en afgeronde hoeken.
  2. Voeg een paragraaf <p> toe met info (flavor) over de Pokémon.
  3. Voeg bovenaan 2 knoppen toe met de tekst Vorige en Volgende. Geef deze respectievelijk het attribuut @click="prev" en @click="next". Dit zijn speciale attributen van het Vue framework. De functies prev en next staan al gedefinieerd in het pokemon.js dat je eerder inlaadde.
  4. Geef de eerste 5 aanvallen van de Pokémon weer in een ongeordende lijst <ul>.
  5. Plaats een link naar een relevante Wikipedia pagina onderaan je website.
  6. Sluit af met een copyright sectie in een <footer>. Maak het lettertype hiervan kleiner en maak de tekst licht transparant.
  7. Plaats een invoerveld naast de knoppen bovenaan, waarin het id nummer van de Pokémon rechtstreeks ingegeven kan worden. Maak gebruik van <input> tags met de attributen v-model="id" en @input="getPokemon(id)". Zorg ervoor dat er enkel cijfers ingegeven kunnen worden.

Uitbreiding

  1. Pas het lettertype van je titel en inhoud aan.
  2. Geef de titel een gele vulling met blauwe rand.
  3. Toon hoeveel aanvallen deze pokémon op zichzelf kan leren.
  4. Plaats alle info van de pokémon in een kaart met een rand en/of slagschaduw.
  5. Plaats het id van de Pokémon op dezelfde lijn als de naam, maar rechts uitgelijnd.
  6. Toon alle aanvallen en het level waarop deze geleerd worden.
  7. Toon alle types en geef iedere badge met het type een typerende achtergrondkleur.
  8. Zorg ervoor dat de kaart beweegt (bv. roteert) wanneer je er met de muis over zweeft.
  9. Plaats alles horizontaal gecentreerd op de pagina. Tip: CSS flexbox
  10. Verwerk de kleur van de Pokémon in een van de elementen op de pagina.

Werkelijk next level

Zorg ervoor dat bij iedere Pokémon zijn evolution chart verschijnt met sprites van iedere Pokémon in de keten.