Okładka artykułu Nawigacja z wykorzystaniem map obrazków — Wykorzystujemy rzadko używaną opcję HTML
Poradniki

Nawigacja z wykorzystaniem map obrazków

Wykorzystujemy rzadko używaną opcję HTML

Zdjęcie autora Hubert Tulibacki
0

Tworząc unikalne projekty stron internetowych, możemy stanąć przed problemem stworzenia nietypowej nawigacji. Na przykład klient chce, abyśmy zaprojektowali mapę Polski z zaznaczonymi województwami, po kliknięciu na które, pojawi się lista dostępnych punktów sprzedaży. Innym przykładem może być umożliwienie klientowi wybranie odpowiedniego piętra w wizualizacji budowanego bloku i wyświetlenie dostępnych w na nim mieszkań.

W dzisiejszym artykule pokaże dwa sposoby na wykonanie tego typu nawigacji za pomocą HTML i CSS. Pierwszym sposobem będzie wykorzystanie map obrazków – trochę zapomnianej już techniki umożliwiającej zaznaczanie dowolnego elementu na obrazku. Dowiecie się, jak w prosty sposób wygenerować taką mapę za pomocą programu Adobe Fireworks. Inną, jeszcze prostszą techniką, jakiej użyjemy, będzie wykorzystanie CSS do stworzenia podobnego efektu.

Generujemy mapę obrazka

Wspomniałem wcześniej o nawigowaniu po zdjęciu budynku i tym się teraz zajmiemy. Do wygenerowania kodu HTML postanowiliśmy użyć testowej wersji oprogramowania Adobe Fireworks CS6. Moglibyśmy oczywiście zrobić to ręcznie, ale każdy ma z pewnością ciekawsze rzeczy do marnowania czasu.

Do stworzenia tej części tutoriala użyłem zdjęcia budynku pochodzącego z portalu Depositphotos, Wy oczywiście powinniście poszukać czegoś swojego.

Pierwsze, co musimy zrobić, to oczywiście otworzyć nasz plik w programie Fireworks. Ważne, aby wielkość zdjęcia i obszaru roboczego była dokładnie taka, jaką chcemy mieć na stronie. Dodane koordynaty będą względne, więc zmiana wielkości pliku przesunie nam zaznaczenie.

Po otwarciu pliku w programie używany narzędzia Piórko i zaznaczamy obszary, które chcemy, aby były linkami. Ważne, aby jeden link był jednym obiektem w programie. Po zamknięciu krzywej zostanie ona wypełniona kolorem oraz obrysowana. W naszym przypadku nie chcemy, aby było to widoczne, więc usuwamy to z obiektu.

Usuwanie obrysu oraz koloru tła
Usuwanie obrysu oraz koloru tła

W następnym kroku zaznaczamy wszystkie stworzone obiekty i klikamy na nie prawym przyciskiem myszy i z menu wybieramy opcję Wstaw plasterek wielokątny. Następnie w oknie dialogowym wybieramy opcję wielu plasterków. Dzięki temu stworzyły się nam wielokątne plasterki, które Fireworks wykorzysta do zapisania koordynatów w pliku HTML.

Zamiana krzywych na plasterki w programie Fireworks
Zamiana krzywych na plasterki w programie Fireworks

Nowo powstałe plasterki powinny zostać zaznaczone kolorem zielonym.

Pozostało nam już tylko zapisać wszystko do HTML. Robimy to za pomocą opcji Eksportuj dostępnej w menu Plik. W opcjach zaznaczamy odpowiednio:

  • Eksportuj: HTML i obrazy
  • HTML: Eksportuj plik HTML
  • Plasterki: Brak (chyba, że chcemy, aby plik wyjściowy został pocięty)
  • Strony: Bieżąca strona
Zapisywanie koordynatów z Fireworks do HTML
Zapisywanie koordynatów z Fireworks do HTML

Kod, który otrzymamy będzie wyglądał podobnie do tego:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>2</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--Fireworks CS5 Dreamweaver CS5 target.  Created Sat Sep 15 00:05:22 GMT+0200 2012-->
</head>
<body bgcolor="#ffffff">
<img name="n2" src="2.jpg" width="640" height="532" border="0" id="n2" usemap="#m_2" alt="" /><map name="m_2" id="m_2">
<area shape="poly" coords="585,120,312,44,251,136,199,127,106,319,107,350,190,233,171,231,164,226,178,206,191,188,236,195,280,200,281,194,315,165,593,216,585,120,585,120" href="javascript:;" alt="" />
<area shape="poly" coords="593,215,314,164,281,194,281,200,190,188,167,226,170,232,191,233,107,351,103,396,166,361,164,348,190,330,286,336,285,330,317,314,601,337,593,215" href="javascript:;" alt="" />
<area shape="poly" coords="607,465,318,479,273,471,222,476,103,451,105,398,165,362,165,347,189,330,288,337,285,329,319,315,600,338,607,465" href="javascript:;" alt="" />
</map>
</body>
</html>

Tagi, które nas interesują, to img, map oraz area. W tagu img atrybut usemap informuje przeglądarkę, którą mapę ma nałożyć na obrazek. Podajemy w nim identyfikator elementu map razem ze znakiem #, który znamy z CSS. Warto pamiętać, że zgodnie ze specyfikacją HTML5, atrybuty idname muszą w elemencie map mieć tą samą wartość. Element area zawiera następujące atrybuty: shape informuje o kształcie, jaki opisujemy, w naszym przypadku jest to poly, czyli wielokąt. Atrybut coords zawiera współrzędne niezbędne do wytyczenia figury (wielokąta) na obrazku. Współrzędne te, to punkty na obrazku w formacie x,y,x,y,x,y,(...). Pozostałe atrybuty są identyczne jak elemencie a. Po usunięciu niepotrzebnych elementów wygenerowanych przez program, mój kod wygląda następująco:

<img src="budynek.jpg" usemap="#budynek" alt="Budynek" />
<map name="budynek" id="budynek">
    <area shape="poly" coords="585,120,312,44,251,136,199,127,106,319,107,350,190,233,171,231,164,226,178,206,191,188,236,195,280,200,281,194,315,165,593,216,585,120,585,120" href="#" alt="Piętro 3" />
    <area shape="poly" coords="593,215,314,164,281,194,281,200,190,188,167,226,170,232,191,233,107,351,103,396,166,361,164,348,190,330,286,336,285,330,317,314,601,337,593,215" href="#" alt="Piętro 2" />
    <area shape="poly" coords="607,465,318,479,273,471,222,476,103,451,105,398,165,362,165,347,189,330,288,337,285,329,319,315,600,338,607,465" href="#" alt="Piętro 1" />
</map>

Gdy mamy już HTML, możemy przystąpić do nadawania wyglądu naszej mapie. Niestety – mapom obrazków nie da się po prostu nadać wyglądu za pomocą arkuszy CSS. Trzeba posłużyć się do tego celu skryptem do jQuery o nazwie ImageMapster. Pełnia jego możliwości opisana jest na stronie domowej pluginu. Ja użyłem następującej konfiguracji:

$('img[usemap]').mapster({
    fillColor: 'ffffff',
    fillOpacity: 0.3,
    stroke: true,
    strokeColor: 'ffffff',
    strokeWidth: 3,
    clickNavigate: true,
    isSelectable: false,
    isDeselectable: false
});

Kolejne opcje oznaczają: kolor wypełnienia, przeźroczystość wypełnienia, aktywację obramowania, kolor obramowania, szerokość obramowania, włączenie podążania za adresem w atrybucie href (domyślnie ta opcja jest wyłączona), wyłączenie możliwości zaznaczania, wyłączenie możliwości odznaczania. Taka konfiguracja pozwala nam na efektowne podświetlanie pięter po najechaniu na nie. Końcowy kod wygląda następująco:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />

        <title>Wybór piętra</title>

        <style>
            body, html {
                margin: 0px;
                padding: 0px;
                background-color: #ffffff;
            }

            #container {
                width: 640px;
                height: 532px;
                position: absolute;
                top: 50%;
                left: 50%;
                margin-top: -266px;
                margin-left: -320px;;
            }

            #container img {
                width: 640px;
                height: 532px;
            }
        </style>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
        <script src="imagemapster.js"></script>
        <script>
            $(function() {
                $('img[usemap]').mapster({
                    fillColor: 'ffffff',
                    fillOpacity: 0.3,
                    stroke: true,
                    strokeColor: 'ffffff',
                    strokeWidth: 3,
                    clickNavigate: true,
                    isSelectable: false,
                    isDeselectable: false
                });
            });
        </script>
    </head>
    <body>

        <div id="container">
            <img src="budynek.jpg" usemap="#budynek" alt="Budynek" />
            <map name="budynek" id="budynek">
                <area shape="poly" coords="585,120,312,44,251,136,199,127,106,319,107,350,190,233,171,231,164,226,178,206,191,188,236,195,280,200,281,194,315,165,593,216,585,120,585,120" href="#" alt="Piętro 3" />
                <area shape="poly" coords="593,215,314,164,281,194,281,200,190,188,167,226,170,232,191,233,107,351,103,396,166,361,164,348,190,330,286,336,285,330,317,314,601,337,593,215" href="#" alt="Piętro 2" />
                <area shape="poly" coords="607,465,318,479,273,471,222,476,103,451,105,398,165,362,165,347,189,330,288,337,285,329,319,315,600,338,607,465" href="#" alt="Piętro 1" />
            </map>
        </div>

    </body>
</html>

Efekt zastosowania tego kodu powinien być następujący:

Budynek z nałożonym zaznaczeniem piętra
Budynek z nałożonym zaznaczeniem piętra
A bez JavaScriptu się da?

Da. Jest to nawet o wiele lepsze rozwiązanie, jednak posiada pewien minus – nie zadziała na Internet Explorer poniżej wersji 9. Powyższy kod zmienia się wtedy na:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />

        <title>Wybór piętra bez JavaScript</title>

        <style>
            body, html {
                margin: 0px;
                padding: 0px;
                background-color: #ffffff;
            }

            #container {
                width: 640px;
                height: 532px;
                position: absolute;
                top: 50%;
                left: 50%;
                margin-top: -266px;
                margin-left: -320px;;
            }

            #container img {
                width: 640px;
                height: 532px;
                display: block;
                position: absolute;
                left: 0px;
                top: 0px;
            }

            #container svg {
                width: 640px;
                height: 532px;
                position: absolute;
                left: 0px;
                top: 0px;
            }

            #container svg .floor {
                fill: transparent;
            }

            #container svg .floor:hover {
                fill: rgba(0, 0, 0, 0.3);
                stroke: #ffffff;
                stroke-width: 3;
            }
        </style>
    </head>
    <body>

        <div id="container">
            <div style="position: relative;">
                <img src="budynek.jpg" alt="Budynek" />

                <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
                    <a xlink:href="#"><polygon class="floor" points="585,120 312,44 251,136 199,127 106,319 107,350 190,233 171,231 164,226 178,206 191,188 236,195 280,200 281,194 315,165 593,216 585,120 585,120" /></a>
                    <a xlink:href="#"><polygon class="floor" points="593,215 314,164 281,194 281,200 190,188 167,226 170,232 191,233 107,351 103,396 166,361 164,348 190,330 286,336 285,330 317,314 601,337 593,215" /></a>
                    <a xlink:href="#"><polygon class="floor" points="607,465 318,479 273,471 222,476 103,451 105,398 165,362 165,347 189,330 288,337 285,329 319,315 600,338 607,465" /></a>
                </svg>
            </div>
        </div>

    </body>
</html>

Jak widać, do stworzenia zaznaczenia użyłem zagnieżdżonego kodu SVG, który pozwala nam również na rysowanie wielokątów. Samo oznaczanie punktów rysowania figury jest dość podobne, jak w przypadku map obrazków. Musimy jedynie usunąć co drugi przecinek. Figury narysowane za pomocą SVG możemy stylować, ale używają one nieco innych atrybutów CSS, niż elementy HTML. Składnia zagnieżdżonego w kodzie linku też musi być trochę inna, żeby działał.

Wszystko co trzeba zrobić po napisaniu odpowiedniego kodu, to nałożyć ustawić SVG wymiary obrazka i ustawić go dokładnie nad nim. Będzie to wtedy wyglądało i zachowywało się jak mapa.

Prosta nawigacja na obrazku

Jeśli nie potrzebujemy używać skomplikowanych kształtów i wystarczą nam kółka oraz kwadraty, do stworzenia nawigacji możemy wykorzystać każdy element HTML, wykorzystując do tego pozycjonowanie. Aby to zilustrować, stworzyłem prostą nawigacją mającą na celu wybór płyty (w celu chociażby przejrzenia jej playlisty), wykorzystując jeden obrazek. Zdjęcia wykorzystane w tej części także pochodzą z serwisu Depositphotos (1, 2 ,3, 4).

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />

        <title>Wybór płyty</title>

        <style>
            body, html {
                margin: 0px;
                padding: 0px;
                background-color: #ffffff;
            }

            #container {
                width: 1200px;
                height: 300px;
                position: absolute;
                top: 50%;
                left: 50%;
                margin-top: -150px;
                margin-left: -600px;
            }

            #container nav {
                position: relative;
                width: 1200px;
                height: 300px;
                background: transparent url('cd.png') scroll no-repeat center center;
            }

            #container nav a {
                width: 294px;
                height: 294px;
                position: absolute;
                left: 0px;
                top: 3px;
                border-radius: 300px;
            }

            #container nav a:hover {
                -webkit-box-shadow: 0px 0px 30px rgba(45, 148, 214, 0.5);
                -moz-box-shadow: 0px 0px 30px rgba(45, 148, 214, 0.5);
                box-shadow: 0px 0px 30px rgba(45, 148, 214, 0.5);
            }
        </style>
    </head>
    <body>

        <div id="container">
            <nav>
                <a href="#" style="left: 3px;"></a>
                <a href="#" style="left: 303px;"></a>
                <a href="#" style="left: 603px;"></a>
                <a href="#" style="left: 903px;"></a>
            </nav>
        </div>

    </body>
</html>

Każdy element a ustawiłem tak, aby znajdował się dokładnie nad płytą. Następnie za pomocą atrybuty border-radious w CSS zrobiłem z niego koło, aby kształtem przypominał płytę. Ostatnim etapem było dodanie cienia, który pojawia się po umieszczeniu kursora nad płytą.

Zaznaczanie różnych obszarów jednego obrazka
Zaznaczanie różnych obszarów jednego obrazka

Ta metoda jest niebywale prosta i działa z każdą przeglądarką. Jej ograniczeniem jest jednak to, że nie możesz tworzyć bardziej wymyślnych kształtów niż prostokąt (ew. prostokąt z zaokrąglonymi rogami) i koło. Można obejść ten problem łącząc ze sobą kilka elementów, tak jak zrobił to Łukasz Popardowski tworząc klikalną mapę Polski. Połączył on kilkadziesiąt elementów HTML i pokrył nimi całe województwo, co daje wrażenie, że całość zrobiona jest za pomocą mapy obrazków, opisanej na początku. Ta technika, chociaż bardzo czasochłonna, umożliwia zastosowanie na prawie każdej przeglądarce bez najmniejszego problemu.

Na zakończenie

Mam nadzieję, że dzięki temu artykułowi dowiedzieliście się, w jaki sposób stworzyć nawigację z każdego obrazka. Należy pamiętać, że tego typu nawigacje rzadko sprawdzają się jako główna nawigacja strony. Użytkownicy bardzo przyzwyczajeni są do klasycznych form nawigowania po stronach. Nawigację obrazkową można jednak zastosować w sytuacjach, gdy stworzenie klasycznej listy odnośników byłoby trudne lub nie intuicyjne. Na przykład: dużo szybciej odnaleźć własne województwo na mapie, niż na liście, nawet alfabetycznej.

Nie zapomnijcie pochwalić się własnymi implementacjami. Miłego kodowania!

To może Cię zainteresować