TP Web — La dernière frontière

La dernière frontière

Dans cet exercice, nous allons découvrir un peu plus le positionnement CSS, ainsi que mettre ensemble du JavaScript, CSS, et HTML dans un petit projet. Plus précisément, nous allons créer une page web sur laquelle un vaisseau spatial va se déplacer.

Mise en place

Pour démarrer, créons le squelette de notre projet. Cette fois, nous allons utiliser une nouvelle organisation par rapport à notre convertisseur de monnaie, ce qui serait un peu plus flexible pour des plus gros projets :

  • espace/

Créer un canevas

Dans notre projet, nous avons besoin de trois genres d’objets : la structure du document, sa mise en forme, et un peu de fonctionnalité. Chacun de ses éléments va aller dans une partie du squelette du projet qu’on vient de créer.

Pour commencer, nous avons besoin d’un petit canevas où mettre note vaisseau spatial. Créez donc dans la page index.html :

<html>
    <head>
        <meta charset="utf-8">
        <title>La Dernière Frontière</title>
    </head>
    <body>
    </body>
</html>

Maintenant, on veut y rajouter notre canevas, avec notre navette dedans. Voici le code à rajouter. Où doit-on le mettre ?

<div id="canvas">
    <img src="media/spaceship.png" id="starship">
</div>

Charger la page

Ça serait bien de vérifier que tout se passe bien lorsqu’on améliore notre projet. Dès maintenant, on a assez pour pouvoir voir quelque chose. Pour des pages simples comme celle qu’on a fait dans le passé, ça suffit de charger le fichier .html directement dans notre navigateur.

Pour des pages plus complexes, les restrictions de sécurité des navigateurs risque de nous empêcher de charger certains éléments des pages. Pour éviter cela, nous allons passer par l’intermédiaire d’un serveur web, qu’on tournera sur notre machine de développement.

Pour faire cela, nous allons utiliser un module de la bibliothèque standard du langage Python. D’abord, on a besoin de naviguer dans le terminal/console vers notre projet (avec cd). Dans le dossier racine de votre projet, lancer l’une des commandes suivantes, selon la version de Python sur votre système. Attention : n’utiliser cette command que dans le dossier de votre projet, car elle donnerait accès à n’importe qui à tous le fichiers du dossier et des sous-dossiers de là où vous la lancer. Pour notre projet, c’est anodin. Si vous la lancer dans votre dossier principal, ça pourrait être un risque de sécurité.

    python -m SimpleHTTPServer 8080
    python -m http.server 8080

La première commande est pour python 2, la deuxième pour python 3.

Une fois la commande lancée, vous pouvez naviguer vers http://localhost:8080 pour accéder à tous les fichiers dans votre dossier projet. Rappelons que index.html est la page donnée par défaut lorsqu’on charge un dossier. C’est à dire, http://localhost:8080/ et http://localhost:8080/index.html sont équivalents et correspondent au fichier index.html dans le dossier racine de votre projet.

Créer un peu de CSS

Pout l’instant, nous avons la structure de nos éléments de la page, mais pas de mise en forme. Par exemple, quelle est la taille de notre canevas ? Où sur la page se trouvera notre navette spatial ?

C’est notre mise-en-page CSS qui s’occupe de tout cela. Dans un premier temps, liez le fichier CSS à notre page web. Rajoutez dans le bloc head de notre page une balise pour charger notre fichier CSS :

<link rel="stylesheet" href="css/main.css">

Puis, rajoutons quelques sélecteurs CSS pour donner un taille à notre canevas et une position à notre navette. Sachant que nous avons mis l’attribut id="canvas" à notre canevas, quel sélecteur permet de le gérer ? Écrivez un sélecteur avec les propriétés nécessaires pour qu’il ait une largeur de toute la page et une hauteur de 600 pixels.

Puis, passons à notre navette. Pour lui, nous voulons fixer sa position dans le canevas. Quel mode de positionnement faut-il utiliser ? On veut qu’il soit à gauche du canevas et centrée verticalement. Quelles valeurs alors faut-il donner pour les propriétés top et left ?

Une fois que ça marche, passons à la fonctionnalité : la gestion de l’animation.

Javascript

Nous allons animer notre navette spatial en utilisant un peu de Javascript. Pour le faire, nous aurons besoin d’une référence en JavaScript vers notre canevas et au spaceship :

// Get the #canvas element from the DOM
const canvas = document.getElementById("canvas");

// Get the #starship element from the DOM
const starship = document.getElementById("starship");

Rappelons que document.getElementById() cherche le DOM pour l’élément dont l’identifiant correspond au paramètre donné.

Nous aurions besoin de créer une variable Javascript qui va stocker la position de la navette pour qu’on puisse s’en servir dans l’animation. Alors, rajoutons :

// Add our own tracking of position in pixels (could be out of sync from DOM)
// NB : assumes CSS positions are expressed in px ; misbehaves for other units
starship.position = { 
    x: parseInt(getComputedStyle(starship).left) || 0, 
    y: parseInt(getComputedStyle(starship).top) || 0 
};

// Add a speed attribute for how many pixels the ship should move each update
starship.speed = 10;

La position est stockée dans un objet avec les propriétés x et y, des entiers extraits du DOM ou initialisés à 0 si pas convertible en entier. On stocke la vitesse de la navette (en pixels) dans une autre propriété, speed.

Nous voudrons que cette position soit mise à jour de façon récurrente pour l’animer à l’écran. Alors, écrivons une fonction loopForever(). Dedans, on va mettre un minuteur pour une fois par seconde. Ce minuteur va déplacer la navette en mettant à jour ses propriétés CSS, va syncroniser sa nouvelle position avec nos variables JavaScript, puis va re-mettre le minuteur pour le faire dans encore une seconde. On trouvera donc quelque chose un peu comme le suivant :

function loopForever() {
    setTimeout( () => {
        starship.position.x += starship.speed;
        starship.style.left = starship.position.x + 'px';  // starship.style overrides CSS properties for this element
        if (starship.position.x < canvas.offsetWidth) { // offsetWidth stores computed width in px
            loopForever(); // keep looping
        }
    }, 250); // set timer for four times per second (250 ms)
}

Puis, pour terminer, on doit démarrer cette boucle dès que la page web termine d’être chargée. Rajoutez alors document.addEventListener("DOMContentLoaded", loopForever); à la fin du javascript.

Il y a juste une dernière chose à faire : dire à la page web de charger le Javascript. Nous allons le mettre à la fin de la page, afin de ne pas ralentir le chargement de la page. Rajouter à la fin du body la balise <script src="js/animate.js"></script>.

Maintenant, lorsqu’on charge la page, on devrait voir notre navette spatiale se déplacer lentement de gauche à droit de l’écran.

Challenges :

  • Faites en sorte que la navette monte ou descende un petit peu avec chaque étape de l’animation, comme si il y avait des courants dans l’espace. Pour cela, Math.random() pourrait être utile.
  • Faites en sorte qu’un clic sur la navette change son orientation. Pour faire cela, vous pouvez utiliser element.addEventListener('click', f) ou element est un élément DOM et f est la fonction à appeler lors du clic.
  • Rajoutez des astéroïdes ou des phasers (pistolets) à la navette.
  • Utilisez votre imagination (ainsi que la documentation et votre moteur de recherche préféré)