JavaScript скрипты


Cоздание ролловеров на картах: imagemap + canvas

Размещена 13 августа, 2008 года


Нечто подобное я уже описывал в статье CSS Sprites и их использование. Там описывалось как можно создавать ролловер-эффекты при помощи CSS. В данном примере будем рассматривать использование imagemap + canvas

Ролловер (rollover)

Ролловер (rollover) - это интерактивный графический элемент, к примеру изображение, которое начинает изменяться при наведении на него курсора мыши или при клике. Как правило ролловеры представляют из себя несколько изображений, сменяемых яваскриптом (или через CSS) при определенных событиях. В нашем случае необходимо, чтобы при наведении курсора мыши на участок имэджмапы менялся внешний вид только этого участка, не затрагивая карту в целом. Слабо?

О том, что такое карты изображений, и как их создавать, читаем здесь.
Также предварительно знакомимся с canvas и методом "рисования" многоугольников.

JavaScript и HTML


Итак, мы умеем рисовать карты изображений (HTML) и создавать совершенно произвольные многоугольники (Canvas + JavaScript). Объединяем эти знания и получим карту, на которой можно показывать ролловеры по её отдельным областям. Одолеем простую задачу: затемним участок карты изображения при наведении курсора мыши.

Для этого в верстке будем использовать модель пирога со следующими слоями:
1) Верхний: прозрачный ГИФ, к которому привязана имеджмапа
2) Средний: блок Canvas
3) Нижний: Само изображение с картой.
Естественно, ширина и высота всех слоев равна одна другой.
Смотрим HTML & CSS:
• Код CSS
canvas {position:absolute; top:10px; left:10px; z-index:20;}
img {position:absolute; top:10px; left:10px; border:0;}
.first {z-index:30;}
.last {z-index:10;}

• Код HTML
<!-- Выводим тот самый слоеный пирог -->
<img class="first" src="/images/spacer.gif" width="220" height="140" alt="" usemap="#map1">
<canvas id="canvasId" width="220" height="140"></canvas>
<img class="last" src="/images/articles/pribaltika.gif" width="220" height="140" alt="">

<!-- Разметка имэджмапы -->
<map name="map1" id="imageMapId">
  <area shape="poly" alt="Эстония" coords="144,44, 136,47, 136,51, 145,54, 143,68, 141,73, 142,82, 144,90, 149,93, 149,100, 157,100, 161,102, 166,100, 174,91, 183,88, 183,86, 187,83, 208,83, 208,85, 214,85, 217,80, 217,78, 210,76, 205,69, 206,62, 198,43, 198,40, 193,39, 192,30, 186,28, 186,25, 181,24, 181,21, 177,20, 171,14, 168,15, 165,13, 163,17, 158,17, 154,21, 154,24, 156,24, 156,25, 153,25, 144,29, 145,34, 143,39, 151,41, 149,44" href="#Эстония">
  <area shape="poly" alt="Латвия" coords="52,12, 43,16, 52,29, 58,30, 58,36, 56,51, 58,60, 63,61, 67,70, 67,72, 66,75, 71,74, 74,88, 84,106, 84,115, 82,120, 86,123, 90,123, 92,127, 94,133, 100,133, 108,135, 115,137, 128,126, 128,124, 131,123, 131,116, 139,115, 146,115, 146,108, 149,104, 149,93, 144,90, 142,82, 141,73, 143,68, 145,54, 136,51, 136,47, 130,48, 114,57, 108,57, 99,50, 100,39, 107,34, 112,21, 115,21, 115,16, 110,13, 104,6, 89,3, 81,7, 71,3, 63,7, 54,9" href="#Латвия">
  <area shape="poly" alt="Литва" coords="13,80, 13,70, 9,65, 13,63, 13,60, 19,59, 25,59, 31,54, 30,51, 25,43, 26,30, 29,21, 39,16, 43,16, 52,29, 58,30, 58,35, 56,50, 58,60, 63,61, 67,70, 67,72, 66,75, 71,74, 74,87, 84,106, 84,115, 82,120, 77,121, 73,116, 68,117, 57,120, 48,120, 38,115, 34,116, 31,118, 29,118, 29,110, 30,107, 26,105, 10,105, 7,99, 8,93, 3,92, 3,86" href="#Литва">
</map>

Работа для JavaScript

Нам необходимо знать, над какой областью проводит в данным момент пользователь курсором мыши. Для этого "прикрутим" с помощью функции initImageMap обработчики событий mouseover & mouseout для элементов area. Одновременно кешируем в массив координаты. Для определения поддержки клиентским браузером canvas-а воспользуемся функцией canvasBrowser:
• Код JavaScript
function canvasBrowser() {
  // Определяем тип браузера
  var ua = navigator.userAgent.toLowerCase();
  var isIE = (ua.indexOf("msie") != -1 && ua.indexOf("opera") == -1 && ua.indexOf("webtv") == -1);
  var isOpera = ua.indexOf("opera") != -1;
  var isFF = ua.indexOf("firefox") != -1;
  
  var result = false;
  // Разрешим все версии IE
  if (isIE) result = true;
  // Лису разрешим только с полторашки
  else if (isFF) {
    var ffVersion = parseFloat(ua.substring(ua.indexOf("firefox") + 8, ua.length));
    if (ffVersion >= 1.5) result = true;
  // Оперу, начиная с версии 9.0
  } else if (isOpera) {
    var operaVersion = parseFloat(ua.substring(ua.indexOf("opera") + 6, ua.length));
    if (operaVersion >= 9.0) result = true;
  }
  return result;
}

// Кеш координат
var coordsCashe = [];
// Прикручиваем события
function initImageMap() {
  if (!canvasBrowser()) return;
  var map = document.getElementById("imageMapId");
  var area, i;
  for (i = 0; i < map.childNodes.length; i++) {
    area = map.childNodes[i];
    // Проверяем тип узла
    if (area.nodeType != 1) continue;
    // Проверяем, что узел является элементом area
    if (area.nodeName.toLowerCase() != "area") continue;
    // Добавляем ID c ключом массива координат
    area.id = "id" + i;
    // Добавляем к элементу обработчики событий
    area.onmouseover = mouseOverHandler;
    area.onmouseout = mouseOutHandler;
    // Кешируем координаты
    coordsCashe[i] = parseCoords(area.coords);
  }
}

// Обработчик события mouseover
function mouseOverHandler() {
  // Вырезаем индекс для массива координат из ID
  var i = this.id.substring(2, this.id.length);
  // Рисуем многоугольник на полученной области
  drawPoly(
    "canvasId",
    coordsCashe[i]
  );
}
// Обработчик события mouseout
function mouseOutHandler() {
  // Стираем нарисованное в canvas
  clearCanvas("canvasId");
}

// Парсим строку с координатами, перечисленными через запятую, в двумерный массив
function parseCoords(str) {
  var coords = [];
  var buferArray = str.split(",");
  var j = 0;
  for (var i = 0; i < buferArray.length; i++) {
    if (i % 2 == 0) {
      coords[j] = [];
      coords[j][0] = buferArray[i];
    } else {
      coords[j][1] = buferArray[i];
      j++;
    }
  }
  return coords;
}

Теперь функции, занимающиеся отрисовкой многоугольников и их стиранием в canvas:
• Код JavaScript
// Функция, принимающая id тега <canvas> и массив координат
function drawPoly(id, arr) {
  var canvas = document.getElementById(id).getContext('2d');
  // Начинаем отрисовку
  canvas.beginPath();
  for (var i = 0; i < arr.length; i++) {
    // Ставим точку на исходную позицию
    if (i == 0) canvas.moveTo(arr[i][0], arr[i][1]);
    // Рисуем линии от точки к точке
    else canvas.lineTo(arr[i][0], arr[i][1]);
  }
  // Задаем цвет заливки в формате RGBA
  canvas.fillStyle = "rgba(128,128,128,0.7)";
  // Зальем полученный многоугольник цветом
canvas.fill();
}

// Очищаем область Canvas
function clearCanvas(id) {
  var canvas = document.getElementById(id)
  var width = parseInt(canvas.width);
  var height = parseInt(canvas.height);
  canvas = canvas.getContext('2d');
  canvas.clearRect(0, 0, width, height);
}

Дело за малым - собрать все в один HTML-файл.

Пример работы

Совместимость с броузерами


– IE 6;
– Mozilla Firefox 1.5;
– Opera 9.01+;

Готовое решение

Все-таки этот пример является написанным для сабя, так сказать для общего развития и понимания технологии. Стоит так же отметить, что для похожих целей, описанных в данном примере, уже есть готовые решения, в частности скрипт mapper.js

Все права на статью принадлежат сайту fastcoder.org
SAPE все усложнил?

MainLink - простая и прибыльная продажа ссылок!

Последние поступления:

Размещена 10 августа 2020 года

Я по ТВ видел, что через 10 лет мы будем жить лучше, чем в Германии...
Я не понял, что это они с Германией сделать хотят?!

читать далее…

ТехЗадание на Землю

Размещена 14 марта 2018 года

Пpоект Genesis (из коpпоpативной пеpеписки)

читать далее…

Шпаргалка по работе с Vim

Размещена 05 декабря 2017 года

Vim довольно мощный редактор, но работа с ним не всегда наглядна.
Например если нужно отредактировать какой-то файл например при помощи crontab, без знания специфики работы с viv никак.

читать далее…

Ошибка: Error: Cannot find a valid baseurl for repo

Размещена 13 сентабря 2017 года

Если возникает ошибка на centos 5 вида
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
Eg. Invalid release/

читать далее…

Linux Optimization

Размещена 30 июля 2012 года

Prelink

читать далее…

 
Аппарат безъигольной мезотерапии Мезотерапия. Купить аппарат безинъекционной мезотерапии цена в Москве в интернет-магазине. Безинъекционная мезотерапия представляет собой аппаратный метод введения в глубокие слои кожи специальных препаратов.