Carte interactive en HTML5

Comment créer une carte interactive en HTML 5 ?

Comme d'habitude, je fonce sur Google voir ce qui se fait déjà, et je tombe sur ce tutoriel.

Je décide de le suivre puisque c'est globalement ce qu'il me faut. Il me reste à l'adapter pour mes besoins personnels. Je vais essayer de vous donner quelques conseils complémentaires qui pourront vous être utiles.

Le principe est de combiner l'utilisation du SVG, un format de données conçu pour décrire des ensembles de graphiques vectoriels (basé sur XML) avec Raphaël, une bibliothèque javascript qui va permettre d'associer des événements javascript à nos données SVG.

Le SVG

Les coordonnées, dimensions et structures des objets vectoriels sont indiquées sous forme numérique dans le document XML. On ne peut pas ouvrir le fichier avec Paint par exemple. Mais avec Notepad, voici à quoi cela ressemble:

<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
 <g>
  <title>Exemple cercle</title>
  <path fill="#000000" fill-opacity="0" stroke="#0978ab" stroke-width="2" stroke-dasharray="null" stroke-linejoin="round" stroke-linecap="square" d="m174.3175,50c0,-24.68646 19.99603,-44.6825 44.6825,-44.6825c24.68646,0 44.6825,19.99604 44.6825,44.6825c0,24.68646 -19.99603,44.6825 -44.6825,44.6825c-24.68646,0 -44.6825,-19.99604 -44.6825,-44.6825z" id="svg_32"/>
 </g>
</svg>
Ce code affiche un simple cercle. On aurait pu utiliser la balise circle, mais je garde cet exemple pour la suite.

Avant de commencer, nous avons besoin de

Voici le résultat simple que nous obtiendrons à la fin. L'affichage d'information se verra au passage de la souris sur les cercles.


1. Création de la carte

Ouvrez SVG editor. Il ressemble à Paint, et est donc assez facile à utiliser. Je ne rentre pas dans les détails, amusez-vous avec et vous comprendrez vite.
Une fois votre belle carte créée, il faudra la sauvegarder. J'ai surement une technique assez brute et surement pas la plus efficace, mais je n'ai pas cherché plus loin :D
Cliquez sur le bouton "SVG"



Copiez tout et collez dans un fichier .svg (il ne sera pas utile par la suite, c'est plus une sauvegarde si vous voulez modifier la carte par la suite).

2. Partie HTML

Dans notre exemple, la carte est composée de 2 parties distinctes: une zone (ici l'île de la Réunion), où aucune interaction ne sera possible, et une autre partie où on affichera une zone explicative lorsqu'on passera la souris dessus.

<div id="canvas_carte"></div>
<div class="info" id="z1">
 <h2>Saint Denis</h2>
 <p>Youhou !</p>
</div>

Vous avez compris, la div canvas_carte contient la carte entière, et le div info notre explication de notre zone interactive. Remarquez l'id = z1 pour notre première zone interactive.
On oublie pas d'inclure nos fichiers javascript, la librairie raphaël et notre script où nous allons travailler maintenant.


<script src="raphael-min.js" charset="utf-8" ></script>
<script src="script.js" charset="utf-8" ></script>

3. Partie JS

J'essaie de décrire un maximum les choses en commentaire dans le code.

window.onload = function() {
  // création de notre map, qui appelle notre div canvas_carte
  var paper = new Raphael(document.getElementById('canvas_carte'), 436, 416);

// quelques paramètres pour notre zone interactive, testez pour les changements
var attr = {
    fill: "#f5f5f5",
    stroke: "green"
    "stroke-width": 1,
    "stroke-linejoin": "round",
  };
  var zone = {}; // tableau de nos zones interactives
  
  // ouvrez votre fichier svg, trouvez la balise "path" correspondant au contour 
  // de votre carte. Il faut sélectionner tout l'attribut d (du m au z).
  // Copiez le ensuite comme ci-dessous..
  grandeCarte = paper.path("m58.6567,...,0l0,0z").attr(attr);
  // De meme pour les autres zones, sauf que cette fois,
  //on les ajoute au tableau zone
  zone.z1 = paper.path("m200,334c-68,...,17 29,-39 29,-39z").attr(attr);
  // gestion des zones interactives
  var current = null;
  for (var state in zone) {
    zone[state].color = "green";
      (function (st, state) {
          st[0].style.cursor = "pointer";
          st[0].onmouseover = function () {
       current && (document.getElementById(current).style.display = "");
       st.animate({fill: st.color, stroke: "green"}, 300);
              paper.safari();
              document.getElementById(state).style.display = "block";
              current = state;
          };
          st[0].onmouseout = function () {
              st.animate({fill: "#f5f5f5", stroke: "green"}, 300);
              paper.safari();
          };
          
      })(zone[state], state);
  }
}

Vous trouverez l'exemple sur jsFiddle ici.

Pour aller plus loin...

Il se peut que vous ayez à créer des zones de différentes couleurs etc...

Vous pouvez alors créer plusieurs tableaux, avec des paramètres différents.
Ensuite, refaire une boucle for (var state in zone) en changeant zone par votre nouveau tableau..

Une fois le principe compris, vous irez très vite à faire de belles cartes interactives. Vous pourrez ensuite personnaliser davantage, en changeant le mode d'interaction (clic..), le mode d'apparition des explications (pop-up) etc...

J'espère que cette article vous intéressera et vous sera utile. N'hésitez pas à dire ce qu'il manque afin de faire profiter les autres.. Soyez indulgent, c'est mon premier article :D

3 commentaires:

  1. L'explication est très claire, merci :) j'ai pu adapter la carte à ce que je voulais.
    Par contre, étant très limité en JS, je ne vois pas comment faire apparaitre les explications en pop-up, c'est la seule chose qui me manque !
    Merci d'avance !

    RépondreSupprimer
    Réponses
    1. Salut,

      essaie de remplacer le onmouseover par onclick, et adapter ce code:
      http://jsfiddle.net/Kzou/zdPNK/

      Si j'ai un peu de temps, je ferais un exemple.

      Supprimer
  2. Bonjour très bon article, par contre j'ai un image SVG qui represente un schema dentaire qui doit interagir avec un tableau primeface(datatable).
    Dans le tableau y'a 2 colonne représentant representant successivement le numero de la dent et etat; parmi les etats on a (en cour;prevu et fait) je veux faire de tel sorte que si l'etat passe en fait il me colore au niveau du schema la dent correspondante en orange.Merci de votre aide!

    RépondreSupprimer