TP2 - Les librairies et plugins Javascript
Pendant cette séance, vous allez voir un certain nombre de librairies permettant d'enrichir les interfaces : de la pagination d'un tableau à la 3D, il y a de quoi faire !
Gérer des tâches courantes
Les petits composants d'interface
On a déjà vu quelques composants Javascript inclus dans Bootstrap pendant le premier TP : les menus déroulants et le caroussel. Bootstrap en contient un certain nombre :
- Notifications : exemple
- Accordéons : exemple
- Les menus déroulants que l'on a déjà vu
- Fenêtres modales : exemple
- Pagination : exemple
- Popovers : exemple
- Scrollspy : suivre le déroulement de la page, sur le principe de la table des matières à gauche de ma page : exemple
- Tooltips (petits bulles contextuelles) : exemple
Si vous utilisez un framework CSS/JS c'est donc une bonne idée de vérifier la doc pour voir ce qui se fait déjà pour ce style d'éléments. Pas de difficultés particulières pour les utiliser, il suffit de suivre la doc comme vous l'avez fait pendant le TP1. Bien sûr les possibilités ne s'arrêtent pas là.
Autour des tableaux
Si vous avez besoin de présenter des données dans un tableau, vous voudrez sûrement lui ajouter quelques fonctionnalités :
- paginer le tableau si vous avez beaucoup de données à afficher
- permettre à l'utilisateur de trier le tableau en cliquant sur les colonnes
- chercher un champ dans le tableau
Un petit exemple avec la (heureusement !) longue liste des épisodes de Doctor Who et la librairie DataTables basée sur jQuery :
| Titre | Id | Date de diffusion | Durée | Audience | Score |
|---|
Et le code :
Vous trouverez les mêmes utilitaires intégrés avec React (react-bootstrap-table ou react-table) et Vue (Vue-table2).
Vous allez réaliser un tableau paginé similaire à mon exemple vous-même. Cela vous permettra de vous re-familiariser avec le JSON qui est très utilisé de façon générale, pour charger des données dans un tableau, un graphe etc.
- À partir de cette page, réalisez un fichier JSON similaire à celui de l'exemple contenant environ 12 jeux vidéos avec leur titre, leur date de sortie en Europe, leur genre, leur mode et leur prix.
- Adaptez les codes HTML et Javascript de l'exemple afin d'obtenir un tableau paginé, triable et filtrable. Attention, utilisez le serveur Apache (sinon la requête Ajax vers le fichier JSON échouera !)
Autour des dates
Là encore, il existe beaucoup de ressources autour des dates. On ne parle ici que d'interfaces mais vous pouvez jeter un oeil à Moment.js qui facilite la manipulation des dates en JS (leur traitement, leur validation, leur format pour l'affichage). Ici on va plutôt parler des composants graphiques : afficher un sélecteur de dates ou un calendrier complet.
Date Pickers
Les sélecteurs de dates sont des composants qui permettent de sélectionner la date et/ou l'heure en cliquant dans un calendrier. Comme ceci :
Ils sont déjà pris en charge par les navigateurs, malheureusement pas de façon homogène. Chrome et Firefox proposent par défaut un sélecteur pour tous les champs de type input="date" mais ce n'est pas le cas de Safari. Pour les champs datetime là seul Chrome les prend en charge. Il reste utile d'utiliser un plugin pour cela donc. Il doit en exister juste quelques centaines :) Quelques exemples : Date Picker basé sur jQuery, Date Picker basé sur Bootstrap 4, pour React, pour Vue.js.
Afficher un calendrier
Si vous voulez afficher des évènements dans un calendrier, il faudra regarder des librairies un peu plus importantes comme Toast UI Calendar dispo en Javascript, avec un plugin jQuery, avec React, Vues.js et Angular.
Autre solution, intégrer un agenda Google avec une iframe, ça vous permet de gérer le calendrier facilement depuis l'appli de Google et de bénéficier des fonctions de partage.
On obtient le code via le menu de partage du calendrier que l'on souhaite présenter, il suffit de copier-coller !
Et pendant qu'on parle de Google, en passant, pour afficher un itinéraire ou un plan (présentation d'une entreprise, du lieu d'un évènement..), pensez à utiliser Google Maps, vous pouvez intégrer une carte de la même façon, on va le voir justement.
Afficher une carte ou un itinéraire
Si vous n'aimez pas programmer, cette partie va vous plaire, aucun code à l'horizon ! Le but du jeu est de tout d'abord créer votre carte personnalisée puis de l'intégrer à votre page web. On va le faire ensemble.
Vous allez intégrer une carte présentant les différents campus de l'Université sur une page web.
- Rendez vous sur https://www.google.com/maps/d/ et connectez-vous avec votre compte Google (créez-en un si vous n'en avez pas)
- Cliquez sur Créez une carte. Vous devriez arriver sur une carte de la France. Regardez l'interface et les différents boutons.
- Renseignez le titre de la carte : Campus de l'Université de Rouen
- Cherchez l'IUT de Rouen à Elbeuf pour commencer. Ajoutez l'emplacement à votre carte.
- Faites de même pour le campus du Madrillet, de Mont Saint Aignan, de Pasteur, de Martainville et de Evreux. Renommez les repères si besoin.
- Cliquez sur Partager et autorisez l'accès public.
- Cliquez sur Aperçu, qui vous montre votre carte avec vos repères. Cliquez sur Partager puis "Intégrer la carte à mon site". Copiez le code HTML
- Insérez le code HTML obtenu dans une page web et testez (via le serveur Apache !)
Vous devez obtenir ceci dans votre page web :
Certaines de ces fonctions sont accessibles depuis Google Maps, ici vous pouvez en faire un peu plus, et surtout sauvegarder vos cartes.
Gérer des images
Ici on va parler images et animations en 2D et on va commencer par voir les librairies qui permettent de traiter des images.
Travailler des images et des animations
Je vais vous citer les librairies les plus importantes. Prenez le temps d'aller voir les pages de démos pour voir ce qu'il est possible de faire
- d3 - Démos : Un gros morceau - fait le café. Globalement, la librairie a pour objectif la représentation de données. Regardez les démos ça vaudra plus qu'un long discours, les usages sont vastes. Certaines librairies se basent elles-mêmes sur d3, notamment pour les graphes.
- anime - Démos : librairie complète, plutôt légère et sans dépendances.
- velocity - Démos : Concurrent historique d'anime.js, les fonctionnalités sont similaires et il est difficile de les départager
- raphael - Démos sur la même page un peu plus bas : plutôt axée dessin qu'animations, simple d'accès et bien documentée
- Vivus - Démo sur la même page : permet de faire des tracés animés ressemblant à des tracés à la main
On va voir quelques exemples avec d3 que pour ma part je connais le mieux. Si vous avez pris le temps de regarder la page de démo, vous avez pu voir qu'on peut faire à peu près tout et n'importe quoi, d'un simple histogramme à une carte des États-Unis assez simple, une carte des vents sur la planète en temps réel et l'infographie des tous les évènements et personnages de GOT. Bien entendu, pour monter de tels visuels il faut travailler un peu !
On va voir un exemple (assez) simple avec une carte géographique de la Haute Savoie. On ne va bien sûr pas s'ennuyer à tracer nous-mêmes toutes les lignes délimitant les communes, ce serait un travail de titan. Heureusement, on trouve sur GitHub des fichiers au format GeoJSON contenant toutes les coordonnées des communes, départements, régions de France. Téléchargez celui qui contient les coordonnées et tracés des communes de Haute Savoie (ici). Vous pouvez l'ouvrir, vous verrez que ce n'est pas vraiment lisible, ce sont des coordonnées. On va les exploiter avec d3 pour tracer la carte.
Notre fichier HTML ne bougera pas, il contiendra seulement les appels à la librairie d3 à partir du CDN et de notre script JS :
Pour commencer, il faut initialiser les dimensions de la carte et le chemin géographique :
// Taille de la map
const width = 500, height = 500;
// On applique à l'élément svg
const svg = d3.select('#map')
.attr("width", width)
.attr("height", height);
// Initialisation du chemin géographique
const path = d3.geoPath();
Ensuite, il faut déterminer la projection de la carte. Vous savez, c'est le processus pour passez des coordonnées sphériques (la terre est ronde tout ça) à un plan. Les différentes projections sont listées dans la doc au chapitre Géographie/projections mais je vous fais grâce de la lecture.
const projection = d3.geoConicConformal() // la projection à utiliser
.center([6.452823, 46.086301]) // le point à centrer sur la carte
.scale(25000) // l'échelle
.translate([width /2, height /2]); // la transformation à appliquer
path.projection(projection); // on donne notre projection à notre chemin
On va ensuite appliquer un groupe à notre élément svg, c'est lui qui contiendra tous les chemins (chaque tracé délimitant chaque commune)
const communes = svg.append("g");
On peut ensuite charger les coordonnées de notre fichier GeoJSON :
d3.json('hautesavoie.json').then(function(geojson) {
communes.selectAll("path")
.data(geojson.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "#B8B8B8");
});
Voilà, vous pouvez déjà tester, vous verrez apparaître votre carte de la Haute-Savoie avec le tracé des communes :
C'est nul il n'y a pas d'interactions ? Et oui il faut rajouter.. des évènements. Normalement, vous savez faire. Il faut ajouter une div pour les petites bulles et les évènements mouseover et mouseout :
// Ajout des bulles contextuelles au début du fichier JS
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// ... le chargement de la map
// Chargement du JSON avec les évènements en plus
d3.json('hautesavoie.json').then(function(geojson) {
communes.selectAll("path")
.data(geojson.features)
.enter()
.append("path")
.attr('class', 'department')
.attr("d", path)
.style("fill", "#B8B8B8") // Jusqu'ici pas de changement !
.on("mouseover", function(d) { // on entre sur la commune avec la souris
d3.select(this).style('fill', 'orangered');
div.transition()
.duration(200)
.style("opacity", .9);
div.html("Commune : " + d.properties.nom + "
") // On affiche le nom de la commune dans la tooltip
.style("left", (d3.event.pageX + 30) + "px")
.style("top", (d3.event.pageY - 30) + "px")
})
.on("mouseout", function(d) {
d3.select(this).style('fill', '#B8B8B8');
div.style("opacity", 0);
div.html("")
.style("left", "-500px")
.style("top", "-500px");
});
});
Implémentez le code de l'exemple vous-même, vous devez obtenir une carte de la Haute Savoie dont les communes se colorent en vert quand on passe la souris dessus et dont le nom apparaît dans une tooltip.
Faire des graphes
Je me répète, il existe plusieurs librairies. Dans le domaine des graphes, vous en trouverez certaines libres et gratuites quelque soit l'usage, d'autres payantes pour un usage professionnel. En voici quelques unes :
- Chart.js, libre (MIT) et gratuite, on va l'utiliser. Dispo seul, pour React, ou Vue.js
- Echarts (Licence Apache). Dispo seul, pour React, ou Vue.js
- HighCharts (gratuit pour un usage non-commercial uniquement). Dispo seul, pour React, ou Vue.js
- Recharts, librairie React (MIT)
Le fonctionnement est similaire aux librairies concernant les tableaux : on charge les données du graphes via un fichier JSON ou un fichier CSV et on initialise le graphe. Le plus souvent, pas plus de 3 lignes de codes à écrire.
Gérer des vidéos
Pour diffuser de la vidéo sur un site, on peut bien sûr utiliser les players d'origine des navigateurs. Si vous avez besoin de fonctionnalités supplémentaires comme modifier l'apparence du lecteur, le playback, sous-titres, passer des playlists, vous pouvez regarder du côté des librairies VideoJS et Plyr.
Gérer de la 3D
Dernière grande partie : la 3D. La librairie de référence dans le domaine est Three.js. Sur le Web, le composant des navigateurs qui gère la 3D est WebGL. Three.js permet de calculer des rendus avec Canvas (2D donc) ou WebGL en 3D. La librairie permet de charger des modèles depuis 3DS Max, Blender ou Maya et bien sûr brancher des évènements Javascript. Vous pouvez regarder les exemples disponibles sur le site de Three.js ici pour vous donner une idée. Cela va du simple logo en 3D à un jeu vidéo complet. Voici également quelques exemples de jeux réalisés avec Three.js et WebGL : Tower Blocks, The frantic run of the valorous rabbit, Plume.
On ne va pas se lancer dans un jeu :) On va commencer par regarder comment faire un petit cube en 3D avec Three.js pour voir les bases de la librairie (inspiré de cet exemple).
Pour commencer, voici le HTML que l'on va utiliser, il ne contient rien, seulement les chargements de Three.js et notre script.
Place au script. Pour réaliser un rendu avec Three.js, vous aurez toujours besoin d'une scène, d'une caméra (le point de vue) et un renderer qui sera responsable du rendu. Commençons donc par les créer :
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400; // On place la caméra
var renderer = new THREE.WebGLRenderer( { antialias: true } ); // Rendu en WebGL
Vous voyez que la caméra a plusieurs attributs, 4 exactement. Ils correspondent :
- le champ de vue vertical en degrés, 70 ici
- le second est l'aspect ratio (le 16/9 de la tv)
- le plan de clipping proche
- le plan de clipping éloigné
Ensuite, on peut configurer la taille du rendu et l'ajouter au document HTML.
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
Voilà, on a initialisé notre rendu. Reste à créer le cube ! On va commencer par créer une forme de dimensions 200
var geometry = new THREE.BoxGeometry( 200, 200, 200 );
Pour colorer le cube, on utiliser un MeshBasicMaterial. On pourrait utiliser aussi une texture (c'est ce qui est fait dans l'exemple de Three.js).
var material = new THREE.MeshBasicMaterial({color: 'blue'});
On a notre forme et son habillage, on peut créer le cube et l'ajouter à la scène :
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
Le cube est créé et ajouté à la scène. Il faut encore calculer le rendu pour l'afficher. On va aussi faire bouger le cube un petit peu.
function animate() {
requestAnimationFrame( animate ); // On anime
cube.rotation.x += 0.005; // sur l'axe des x
cube.rotation.y += 0.01; // et y
renderer.render( scene, camera ); // On calcule le rendu
}
animate(); // On appelle notre fonction !
Maintenant on va ajouter un gestionnaire d'évènements pour changer la couleur du cube lorsqu'on clique sur la page avec une couleur aléatoire.
document.body.addEventListener("click", function(){
// Modification de la couleur
cube.material.color = new THREE.Color(0xffffff * Math.random());
})
- Implémentez le code de l'exemple vous-même, vous devez obtenir un cube bleu qui gigote et qui change de couleur quand on clique comme ci-dessus.
- Modifiez le code pour que quand on clique, le cube change de couleur mais aussi il rétrécit. Vous devrez utiliser la propriété
scaledu cube sur les axes x, y et z.
Comment choisir quelle librairie utiliser ?
Quelque soit le sujet auquel on s'attaque, vous trouverez à chaque fois beaucoup de librairies. Allez donc taper "SVG javascript libraries" dans Google pour vous en convaincre. On en a déjà parlé pour les frameworks, la problématique est la même pour choisir une plus petite librairie. Bien sûr, il n'y a pas de règles gravées dans le marbre. Souvent, vous n'aurez même pas le choix : les technolologies utilisées ont été déterminées avant votre arrivée dans un projet. L'étendue du choix peut aussi être restreint, pour des questions de compatibilité, de licence... Voici quelques aspects à étudier pour vous aider à déterminer quelle librairie utiliser quand vous êtes libres de choisir :
- L'objectif à accomplir : évident mais.. L'objectif doit être clair et bien posé dès le début. Par exemple, paginer et trier un tableau.
- Les performances : étudier les performances des librairies candidates
- La documentation : commencer à travailler avec une librairie pour réaliser que certaines options sont mal voire pas du tout documentées, c'est désagréable
- Les développeurs : ça rejoint en partie le point précédent, une communauté solide autour d'une librairie fournira le plus souvent une bonne documentation. Il est important que les outils que vous utilisez soient correctement maintenus.
- La licence : vous pouvez vouloir privilégier des licences libres, ou non. Certaines licences sont de plus incompatibles entre elles. Vérifiez toujours ce point, les usages professionnels peuvent être restreints.
Je n'ai pas numéroté par ordre d'importance ces critères, c'est volontaire. En fonction de vos objectifs, de la complexité de ce que vous développez, de vos connaissances, il vous faudra pondérer ces critères. Pour une librairie que vous connaissez déjà bien, l'importance de la doc est moindre. Au contraire, si vous débutez sur un sujet, vous pourrez vouloir choisir une librairie qui vous fournit une documentation et une communauté solides, au détriment des performances.
À vous
Durant le reste de cette séance et la séance suivante, vous devrez créer votre propre rendu 2D ou 3D à l'aide de l'une de ces librairies :
- d3
- animate
- ThreeJS
Vous êtes libres de créer ce qui vous plaît et vous pouvez bien sûr vous inspirer des exemples disponibles que nous avons vu ou fait pendant la séance (vous inspirer seulement !). Seule contrainte : votre rendu devra réagir à au moins 2 évènements.
Vous intégrerez votre rendu dans la page laissée vierge dans le site réalisé pour le TP1.
Le projet complet devra être rendu sur UniversiTICE avant le dimanche 31 mars à 23h55 dans le dépôt correspondant à votre groupe sur la page du cours.
Le barème prendra en compte la qualité du code, sa rédaction, sa documentation. Vous pouvez vous reporter au barème du premier TP. Quatre points seront réservés à la complexité de votre rendu.