Signets, scènes et visites

Les signets sont des vues enregistrées par l'auteur ; les scènes sont des vues que vous capturez : la caméra, ce qui est affiché, les segments, la sélection et le fond de carte, réunis dans un simple objet que vous pouvez stocker n'importe où. La même scène devient un lien qui ouvre la carte exactement dans cet état, et une visite lit une séquence de vues enregistrée par l'auteur.

Ouvrir cet exemple seul

Points à remarquer

  • getBookmarks() est vide sauf si l'auteur a coché Show a bookmarks control lors de la publication : c'est l'auteur qui décide si des signets sont proposés.
  • Une scène survit à une republication : les parties qui n'existent plus sont ignorées et signalées, le reste s'applique.
  • sceneToUrl place la scène dans le fragment de l'URL, que les navigateurs n'envoient jamais à un serveur.
  • Pendant la lecture d'une visite, viewChanged porte reason: "tour".

Le code

La page complète. Remplacez l'identifiant de publication par le vôtre, et demandez à l'auteur de la carte d'ajouter votre site à ses origines autorisées.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Bookmarks, scenes and tours - Icon Map Embed API</title>
  <link rel="stylesheet" href="https://www.icon-map.com/embed-examples/examples.css"> <!-- demo styling only -->
</head>
<body>
  <div class="ex-bar">
    <span class="ex-label">Bookmarks</span>
    <span id="bookmarks" class="ex-chips"></span>
    <span class="ex-spacer"></span>
    <button id="tour">Play the tour</button>
  </div>
  <div class="ex-bar">
    <span class="ex-label">Your own views</span>
    <button id="save">Save this view</button>
    <span id="saved" class="ex-chips"></span>
    <span class="ex-spacer"></span>
    <button id="link">Copy a link to this view</button>
    <button id="reset">Reset</button>
  </div>
  <div class="ex-main"><div id="map"></div></div>

  <script src="https://www.icon-map.com/js/iconmap-embed/2/iconmap-embed.umd.min.js"></script>
  <script>
    const el = document.getElementById("map");
    const map = IconMapEmbed.embed(el, {
      publishId: "pub_...",
      // The map is a globe: let this page's own background show in the space around it.
      background: "transparent",
      // This page draws its own bookmark bar, so hide the map's.
      chrome: { bookmarksBar: false, layerControl: false },
      visibility: { visuals: { "chart-continent": false, "slicer-continent": false, "slicer-size": false, "slicer-capital": false } },
      events: ["bookmarkApplied", "tourStateChanged"],
    });
    map.ready.catch((error) => console.error(error.code, error.message));

    // --- bookmarks: views the map's author saved ---------------------------------
    map.getBookmarks().then((bookmarks) => {
      for (const bookmark of bookmarks) {
        const button = Object.assign(document.createElement("button"), { textContent: bookmark.name, title: bookmark.description ?? "" });
        button.dataset.bookmark = bookmark.id;
        button.onclick = () => map.applyBookmark({ bookmarkId: bookmark.id, animate: true });
        document.getElementById("bookmarks").append(button);
      }
    });
    map.on("bookmarkApplied", ({ bookmarkId }) => {
      for (const b of document.querySelectorAll("[data-bookmark]")) b.classList.toggle("on", b.dataset.bookmark === bookmarkId);
    });

    // --- scenes: views YOU capture - camera, layers, slicers, selection, basemap --------
    // A scene is a plain object: keep it in localStorage, your database, a URL.
    const scenes = [];
    document.getElementById("save").onclick = async () => {
      const scene = await map.captureScene();
      const index = scenes.push(scene);
      const button = Object.assign(document.createElement("button"), { textContent: `View ${index}` });
      button.onclick = () => map.applyScene({ scene, animate: true });
      document.getElementById("saved").append(button);
    };

    // The same scene as a link that opens the map exactly here - no code on the page that opens it.
    document.getElementById("link").onclick = async () => {
      const scene = await map.captureScene({ include: ["camera", "visibility", "slicers"] });
      const link = IconMapEmbed.sceneToUrl(map.iframe.src.split("#")[0], { scene });
      await navigator.clipboard.writeText(link);
      document.getElementById("link").textContent = "Copied";
      setTimeout(() => (document.getElementById("link").textContent = "Copy a link to this view"), 1500);
    };

    document.getElementById("reset").onclick = () => map.resetScene();

    // --- tours: a sequence of views the author recorded -------------------------------
    let playing = null;
    document.getElementById("tour").onclick = async () => {
      if (playing) return map.stopTour();
      const [tour] = await map.getTours();
      if (tour) map.playTour({ tourId: tour.id });
    };
    map.on("tourStateChanged", ({ tourId, state }) => {
      playing = state === "ended" ? null : tourId;
      document.getElementById("tour").textContent = playing ? "Stop the tour" : "Play the tour";
      document.getElementById("tour").classList.toggle("on", !!playing);
    });
  </script>
</body>
</html>

Pour aller plus loin