Obrazová mapa s hover efektem

Ne jen samými novými technologiemi a frameworky živ je webař. Někdy je také třeba vymyslet řešení pro, na první pohled triviální, věc – jako třeba interaktivní mapa ČR s vyznačenými kraji, která bude reagovat na „ježdění myší“ a zvýrazňovat kraje (hover) a bude navíc umožňovat mít jeden kraj vybraný.

Živím se jako HTML a CSS kodér, poslední dobou častěji přičichnu i k JavaScriptu. Někdy narazím na zajímavý problém, který se snažím vyřešit – což je případ dnešního článku. Pro někoho bude toto téma objevováním Ameriky, pro někoho objevem nepříliš atraktivního cípu severního Mongolska. Ať už se na vašem globusu poznání budeme pohybovat kdekoliv, dnes se podíváme na „klikací“ obrazovou mapu a trochu ji oživíme.

Zadání

Vytvoříme klikací mapu ČR s hover efektem na jednotlivých krajích. Aby to bylo zajímavější, zachováme barevné označení aktuálně zvoleného kraje a hover efekt ostatních krajů provedeme jinou barvou.

Obrazová mapa

Tvořit samotnou klikací mapu je v podstatě nuda. Na obrázku se vytyčí mnohoúhelníky a elipsy, které po kliku vedou na cílovou stránku. Pro Windows existuje program Handy ImageMapper, který nabízí vcelku pohodlnou cestu k získání potřebných polygonů, ve kterých bude klikací mapa reagovat. Jistě se bude hodit možnost nahlédnout do návodu, jak s programem efektivněji pracovat. Výstup z programu je vhodné upravit, ale to důležité – polygony – umí dobře.

Vytvoříme hranice prvního kraje…

Vytváříme druhý kraj – všimněte si překryvu oblastí (viz tip)

<img src="img/cr.png" id="mapa-cr-img" usemap="#mapa" alt="Mapa ČR" />
        <map name="mapa" id="mapa">
                <area shape="poly" coords="137,35,139,43,146,38" href="?region=kraj1" title="Kraj 1" alt="Kraj 1" />
                <area shape="poly" coords="123,73,117,65,113,67" href="?region=kraj2" title="Kraj 2" alt="Kraj 2" />
                <area shape="poly" coords="125,73,123,82,137,61" href="?region=kraj3" title="Kraj 3" alt="Kraj 3" />
                <area shape="poly" coords="82,84,93,90,101,93,79" href="?region=kraj4" title="Kraj 4" alt="Kraj 4" />
</map>

Ukázka HTML kódu image mapy

Přesto hardcore kodérům nebráním v ručním zápisu jednotlivých souřadnic.

TIP – klikací mapa není puzzle

Polygony se mohou překrývat. První – v ukázce na 3. řádku – bude vykreslen zcela nahoře, klikatelný v celé své ploše. Polygony z následujících řádků se zobrazují pod ním v pořadí jejich zadání. Tedy druhý (4. řádek) bude pod prvním, třetí (5. řádek) pod prvním i pod druhým atd. Polygon z posledního řádku bude vykreslen zcela vespod, překrývají jej všechny dříve definované.

Pokud nemají být na mapě neaktivní plochy – „slepé“ mezery mezi polygony – nemusíte tvořit přesné „švy skládačky“. Začnete-li s definicemi od spodních řádků, můžete si dovolit udělat přesah do sousední plochy. Obrys hranice pak vytyčíte polygonem definovaným o řádek výš, kterým vzniklý přesah „oříznete“.

A Prahu můžete udělat i trochu větší – aby se na ni klikalo pohodlněji. Tak či onak, máme hotovou surovou mapu, kde každý klik vede na patřičnou url.

Příklad: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa.php

Brute force řešení, nebo horská dvojkombinace?

Abych minimalizoval zmatek v názvosloví, přidržím se následujících termínů a jejich užití:

  • Označení – barevná odlišnost aktuálně vybraného kraje na mapě (stránka/pozice kde jsem) – červená
  • Zvýraznění – barevná odlišnost kraje pro hover efekt (kam mohu jít) – žluto-oranžová
  • Rollover – obrázek na pozadí obsahující všechny možnosti zvýrazněných krajů – hover efekt

Využijeme prostou (a tím geniální) Pixyho techniku Rychlé rollovery bez načítání. V čem spočívá? Jeden obrázek umístěný na pozadí bude obsahovat všechny očekávané stavy mapy. Vhodným posouváním pozadí – rolloveru – dosáhneme zobrazení správných obrázků v odpovídajících situacích. Vyhneme se tak nutnosti načítat předem jednotlivé obrázky a také nežádoucímu problikávání obrázků v případě zvýrazňujícího hover efektu, když bychom je načítali až v okamžiku jejich zobrazení.

Moment… Jak vidno, mohli bychom vystačit s jedním obrázkem – rolloverem. Tedy, spíš s plachtou. Při 14 krajích České republiky vychází slušivých 211 kombinací (včetně variant bez/s zvýrazněné a/nebo označené pozice). Tolik mapek se mi dělat nechce. Nehledě na definování jednotlivých stavů zobrazení (i když chápu, že po rozcvičce s polygony někomu „pár XY souřadnic“ může připadat jako procházka růžovým sadem).

Raději zkombinujeme transparentní obrázky obsahující označené kraje a rollover, kterým zvýrazníme kraje pod kurzorem myši. K tomu nám bude stačit rollover čítající 14 zvýrazněných pozic na mapě + jedna základní mapka bez zvýraznění. Stejný bude i počet průhledných obrázků s označenou aktuální pozicí + jeden kompletně průhledný obrázek pro případ mapy bez označené pozice. Tak budeme schopni získat všechny potřebné kombinace. Ještě že neděláme mapu USA! (tu dostanete za domácí úkol – pozn.aut.)

Ukázka výsledné možné kombinace a pohled na vrstvy z jiné perspektivy – červeně označený kraj s transparentním okolím nad mapkou se zvýrazněným krajem

Zde by matematik poznamenal, že řešení existuje – a sbalil si kufry. Proto se rozlučme s teoretiky a hurá na praktické řešení.

Příprava obrázků

Dobrá, trochu jsem blafoval. Krom rolloveru s 15 variantami zvýraznění krajů pro hover efekt a 15 transparentních obrázků s označenými kraji budeme potřebovat ještě dalších 15 obrázků/mapek. Budou to označené kraje doplněné o zbytek „statické“ mapy.

Ukázka hotového rolloveru, tedy pás map se zvýrazněnými jednotlivými kraji

Než mi začnete nadávat – je to zlomek práce. V Gimpu nebo Photoshopu to znamená vypnout/zapnout na pozadí vrstvu s mapou ČR a uložit kopii. Odměnou nám bude fungující a použitelná klikací mapa i bez JavaScriptu a kaskádových stylů – s přidanou hodnotou správně označeného kraje.

Ukázka jedné z dodělávaných mapek s označením kraje – a ani to nebolelo

Získali jsme tedy klikací mapu, která nás kliknutím přesune na odpovídající url. Navíc načteme obrázek mapy, ve kterém je označen aktuálně zvolený kraj.

Příklad: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-oznaceni.php

TIP

Rollover jsem připravil jako řadu mapek poskládaných vedle sebe. Je možné mapky umístit do sloupce či matice (nebo i nahodile). Mnou užitý způsob má svůj význam a dále jej s výhodou využijeme.

JavaScript na scéně

Pomocí JavaScriptu vyměníme obrázek s označeným krajem za jeho transparentního brášku. V příkladu řeším tuto rošádu modifikací cesty k obrázku. Nebráním však nikomu v užívání regulárních výrazů a podobných skopičin – každému dle jeho chuti a schopností.

$(document).ready(function() {
    mapaimage=$('#mapa-cr-img').attr("src"); // získání obrázku klikací mapy
    $('#mapa-cr-img').attr("src", "js/"+mapaimage); // nahrazení obrázku klikací mapy za transparentní variantu
    });

Ukázka mapy s označeným krajem…

…a transparentního brášky, který ji nahradí

Označený kraj nám nyní svítí na svém místě, ale zbytek mapy zatím chybí. Na pozadí spanu #mapacr zobrazíme pomocí CSS připravený rollover. Nyní je výsledek po stránce funkčnosti zdánlivě stejný jako před naším zásahem – mapa s označeným krajem. Jsme však připraveni zvýrazňovat.

Příklad – mapa a rollover, zatím bez hover efektu: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-js.php

Abychom zprovoznili hover efekt, musíme posouvat rollover na pozadí tak, aby se zobrazovala mapka se správným zvýrazněním vzhledem k poloze kurzoru myši nad mapou. Se samotným CSS zde asi nepořídíme. Jak tedy na to?

Jednotlivým krajům v klikací mapě přidělíme čísla. Já je zvolil tak, aby odpovídala jejich pořadí v připraveném rolloveru. Proč? Inu, pomocí událostí onmousmove a onmouseout předáváme JavaScriptové funkci mapa(kraj) informaci (číslo), nad kterým krajem zrovna poletuje kurzor – případně, že jej kurzor opustil. Jelikož známe šířku mapy a pozice jednotlivých zvýraznění jsou uspořádány v souladu s očíslováním v klikací mapě, stačí vynásobit šířkou mapy onou pozicí.

function mapa(kraj) {
    if(kraj < 15) {
        pozice = "-"+(kraj*167)+"px 0px "; // výpočet posunutí rolloveru
        $('#mapacr').css('backgroundPosition', pozice); // přesunutí rolloveru na vypočtenou pozici
    }
}

$(document).ready(function() {
            mapaimage=$('#mapa-cr-img').attr("src"); // získání obrázku klikací mapy
            $('#mapa-cr-img').attr("src", "js/"+mapaimage); // nahrazení obrázku klikací mapy za transparentní variantu
    });

Dostaneme počet pixelů, o které se má rollover posunout, aby byla vidět jeho správná část. Je-li kurzor myši nad aktuálně označeným krajem, je vidět pouze původní označení – zvýraznění je skryto pod ním. To vnímám jako žádoucí. Proč uživateli zvýrazňovat stránku/kraj, kde již je?!

Příklad: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-js-hover.php

TIP

Zpřeházíte-li v kódu čísla u krajů, získáte efektní aprílový žertík.

A když bude vypnutý kaskádový styl…

Vypnutý JavaScript máme vyřešený v základní verzi klikací mapy – však jsme kvůli tomu dělali obrázky navíc. Ale co když je uživatel škodolibý tester, který si JavaScript ponechá funkční a poťouchle si vypne CSS? I taková situace může nastat, naštěstí není těžké ji ošetřit.

Nejprve – co by se stalo s fungujícím JavaScriptem a vypnutými CSS? JavaScriptem vyměníme výchozí mapu za jejího progumovaného průhledného brášku s označenou aktuální pozicí. Ač by klikací mapa jako taková stále fungovala, s obrázkem bez „zmapovaného“ okolí by nebylo ovládání žádný med. Práci s takovým výtvorem bych vám nepřál, přesto, zkuste si pro zajímavost příklad.

Škodolibá verze: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-js-no-css-1.php

Sympatičtější verze předchozího: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-js-no-css-1.php?region=plzen­sky-kraj

Nejjednodušší mi v tuto chvíli připadá následující test: Pomocí JavaScriptu vytvoříme span s nápaditým ID jquerytestspan. V CSS mu nadefinujeme barvu pozadí. Tuto barvu načteme JavaScriptem do proměnné a porovnáme ji s očekávanou hodnotou. Budou-li se barvy shodovat, je CSS použito a provedeme JavaScriptové nahrazení obrázku klikací mapy. Pokud se barva neshoduje, CSS soubor není použit a proto výměnu neprovedeme – klikací mapa nám tak zůstává stále fungující a použitelná, byť ochuzena o hover efekt. V každém případě testovací span opět odstraníme, aby nám nedělal v kódu zbytečnou paseku.

Příklad: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-js-no-css-2.php

Někde RGB, někde hexa

Už to vypadá, že je to hotové, že? A zkusili jste se na výsledek podívat v Opeře nebo Internet Exploreru? Sranda že? Najednou nám tu nefunguje zvýraznění. A přitom v příkladu bez kontroly přítomnosti CSS (https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/mapa-js-hover.php) vše jelo jak po másle… Na vině je podmínka, lépe řečeno její neúplnost. Opera a Internet Explorer nám vrací zápis v hexa formátu, Chrome a Firefox hrdě vypsaly jeho podobu v RGB. Pokud podmínku doplníme o kontrolu hexadecimálního zápisu barvy, dostaneme…

Příklad: https://www.zdrojak.cz/wp-content/uploads/ukazka/ma­pa/

Závěr

A máme konečně hotovo. Klikací mapa je funkční, rollover vesele rolloveruje, uživatele bez JavaScriptu nezmateme a vykuky s vypnutým CSS také obsloužíme k jejich spokojenosti. Dokonce neurazíme omezenou funkčností ani uživatele různých prohlížečů a ušetřili jsme si zbytečnou práci se 166 mapkami navíc.

Máte-li pocit, že tu bylo vynalézáno kolo, snad jsem jej nevymyslel příliš hranaté. Řešení příkladu jistě není jediné možné a já nemám (zatím…) patent na rozum. Třeba test CSS by šel realizovat jinak – kontrolou definice rolloveru, čímž by se ušetřilo generování/ zmizíkování testovacího spanu. A možná je vše špatně a k tomu ještě zbytečně překombinované. Proto se těším na vaše nápady a vylepšení v komentářích.

První aktivní webové krůčky uskutečnil v roce 2002. Krom kodéřiny rád testuje a zkouší nové technologie/programy (aktuálně GNU/Linux), vektorově kreslí, hraje na housle a sem tam píše do šuplíku. Brblá tak, až se mu to stalo druhým jménem.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 27

Přehled komentářů

reggae jQuery Map Hilight
petr.steinbauer Vynalézání kola
Brbla80 Re: Vynalézání kola
Opravdový odborník :-) Re: Vynalézání kola
chleba prehistoricka vec
Brbla80 Re: prehistoricka vec
chleba Re: prehistoricka vec
Brbla80 Re: prehistoricka vec
Jakub Vrána Pokud by se někomu nechtělo obrázky dělat ručně
Oldis Re: Pokud by se někomu nechtělo obrázky dělat ručně
chleba kdo by chtel delat nad mapovym API
karmi Raphael.js
jlx Re: Raphael.js
_Martin Re: Raphael.js
chleba canvas mapa
Miloslav Lešetický Re: canvas mapa
chleba Re: canvas mapa
J.L. Re: canvas mapa
chleba Re: canvas mapa
Opravdový odborník :-) Vektory, ne bitmapy
chleba Re: Vektory, ne bitmapy
Fred šikovné
Fred canvas
mzahradnicek Cesko-Slovensko
josefrichter taky jedno canvas řešení
Phate Klikací mapa
Roman Klikací mapa s hover efektem
Zdroj: https://www.zdrojak.cz/?p=3492