Клуб API Карт

Изменение внешнего вида объектов

rodlex
28 октября 2009, 18:57

Стандартный внешний вид меток, балуна, ломанной, многоугольника и всплывающей подсказки можно поменять с помощью стилей.

Стиль – это набор параметров, который позволяет задать внешний вид объектов на карте. Чтобы создать стиль, необходимо создать экземпляр класса YMaps.Style.

Сам стиль является контейнером, содержащем в себе стили для конкретных объектов (значка метки, ломанной линии и т. д.).
Например, за оформление значка метки отвечает поле iconStyle, в которое должен быть записан указатель на объект класса YMaps.IconStyle.

// Создание нового стиля
var style = new YMaps.Style();
 
// Стиль для оформления значка метки
style.iconStyle = new YMaps.IconStyle();
 

При создании любого оверлея в конструктор класса можно передавать как указатель на стиль, так и ключ.

Ключ – это строка, которая является уникальным идентификатором стиля.

В наименовании ключа можно использовать любые символы, однако рекомендуется создавать свое пространство имен и в нем задавать пользовательские стили. Пространство имен и имя стиля разделятся символом "#" (решетка). Все стандартные стили находятся в пространстве имен “default”. Например, «deafult#greenPoint”, «deafult#redPoint”, «deafult#smallWhitePoint” и т. д.

Продемонстрируем на фрагменте кода оба способа задания стиля.

// Создание стиля
// Подробнее о смене значка на любое изображение будет рассказано далее
var style = new YMaps.Style();
style.iconStyle = new YMaps.IconStyle();
style.iconStyle.href = "http://api-maps.yandex.ru/i/0.3/micro/pmgns.png";
style.iconStyle.size = new YMaps.Point(28, 29);
style.iconStyle.offset = = new YMaps.Point(-7, -28);
 
// В конструктор класса передается указатель на стиль
var placemark = new YMaps.Placemark(map.getCenter(), {style : emptyStyle});
 
// Стиль задан с помощью ключа
var placemark2 = new YMaps.Placemark(map.getCenter(), {style : "default#greenPoint"});

Ключ используется для того, чтобы выбрать нужный стиль из хранилища стилей YMaps.Styles.
Использовать хранилище стилей удобно, когда необходимо обращаться к стилям до их создания. Например, когда стили создаются в отдельном файле и загружаются после создания меток.

В хранилище можно добавить свои стили с помощью метода add(), а удалять – с помощью метода remove().

// Добавим созданный стиль в хранилище
YMaps.Styles.add("example#blueIcon", styleExample);

Теперь к добавленному стилю можно получить доступ по его ключу:

var style = YMaps.Styles.get("example#blueIcon");

Стиль можно задавать не только в конструкторе оверлея в виде параметра, но и с помощью метода setStyle().

placemark.setStyle("default#smallRedPoint");

С помощью метода setStyle() можно менять стиль оверлеев динамически во время выполнения скрипта.

Рассмотрим подробнее механизм стилей на примере смены значка у метки.

В API существует ряд стандартных, предопределенных стилей для значков с различными цветовыми решениями и размерами. Полный их список приведен в Справочнике по программному интерфейсу.

Возьмем стандартный стиль с ключом «deafult#greenPoint» и зададим его метке, тем самым поменяем цвет стандартного значка с светлого-голубого на зеленый.

var placemark = new YMasp.Placemark(map.getCenter(), {style : "default#greenPoint"});
map.addOverlay(placemark);

В качестве значка метки можно использовать любое пользовательское изображение.

Сменим значок на произвольное изображение.
Для этого необходимо создать экземпляр класса YMaps.IconStyle и определить у него три поля: ссылку на изображение (href), размер значка (size) и смещение изображения относительно точки позиционирования значка (offset).

// Создание стиля для метки
var styleExample = new YMaps.Style();
styleExample.iconStyle = new YMaps.IconStyle();
styleExample.iconStyle.href = "http://info.maps.yandex.net/api/i/steelblue/dot.png";
styleExample.iconStyle.size = new YMaps.Point(26, 46);
styleExample.iconStyle.offset = new YMaps.Point(-22, -46);
 
// Создание метки с измененным значком
var placemark = new YMasp.Placemark(map.getCenter(), {style : styleExample});
map.addOverlay(placemark);

Посмотреть пример на отдельной странице 

Создадим пустой стиль:

var styleEmpty = new YMaps.Style();

Если применить вышеприведенный стиль к любому из оверлеев, то их внешний вид не изменится, хотя подстили не были определены.

Дело в том, что недостающие стили наследуются от родительского. Если родительский стиль не указан, то недостающие стили берутся из параметров по умолчанию.

При наследовании дочерний стиль перенимает у родительского все свойства, которые не определены в дочернем. После процедур наследования стиль дополняется недостающими параметрами из значений по умолчанию.

Рассмотрим наследование стилей. Для этого разместим на карте несколько меток со значками футбольного, баскетбольного и теннисного мячей. Их размеры одинаковы и равны 20х20 px. Чтобы не дублировать описание стилей для каждой метки, создадим базовый стиль, который будет содержать информацию о размерах и смещении меток. Стили всех меток унаследуем от базового стиля.

// Создание базового стиля
var baseStyle = new YMaps.Style();
baseStyle.iconStyle = new YMaps.IconStyle();
baseStyle.iconStyle.offset = new YMaps.Point(-10, -10);
baseStyle.iconStyle.size = new YMaps.Point(20, 20);
 
// Наследуемся от базового стиля
var styleFootBall = new YMaps.Style(baseStyle);
styleFootBall.iconStyle = new YMaps.IconStyle();
styleFootBall.iconStyle.href = "/img/football.png";
 
// Наследуемся от базового стиля
var styleBasketBall = new YMaps.Style(baseStyle);
styleBasketBall.iconStyle = new YMaps.IconStyle();
styleBasketBall.iconStyle.href = "/img/basketball.png";
 
// Наследуемся от базового стиля
var styleTennis = new YMaps.Style(baseStyle);
styleTennis.iconStyle = new YMaps.IconStyle();
styleTennis.iconStyle.href = "/img/tennis.png";

Посмотреть пример отдельном окне 

Для элементов группы можно задать единый стиль. Для этого нужно передать ключ стиля (или указатель на стиль) в качестве параметра в конструктор класса YMaps.GeoObjectCollection и он будет применен ко всем элементам группы автоматически (стиль для группы можно также задать с помощью метода setStyle()):

var gCollection = new YMaps.GeoObjectCollection("default#greenPoint");

Посмотреть пример в отдельном окне

Метки, находящиеся в группе, наследуют параметры стилей группы, но данная операция имеет более низкий приоритет, чем непосредственное наследование стилей.

// Для всех меток группы задается зеленый значок
var gCollection = new YMaps.GeoObjectCollection("default#greenPoint");
gCollection.add([
    // У этой метки определен стиль - красный значок
    // Стиль группы не перекроет стиль этого объекта
    new YMaps.Placemark(new YMaps.GeoPoint(37.518234,55.708937), {style: "default#redPoint"}),
    new YMaps.Placemark(new YMaps.GeoPoint(37.514146,55.722294))
]));

Таким образом группа будет содержать две метки с красным и зеленым значками соответственно.

Стоит отметить, что если группы вложены одна в другую, то при формировании стиля для элементов группы будет учитываться и стиль родительской группы. Таким образом могут быть созданы целые цепочки наследования. По той же схеме происходит наследовании стилей, т. е. когда родительский стиль сам имеет своего родителя.

Рассмотрим цепочку наследования из трех стилей. В первом определим стиль обводки многоугольника, во втором – стиль заливки, а в третьем – стиль для значка метки. Пусть третий стиль наследуется от второго, а второй – от первого.

// Стиль обводки многоугольника
var stylePolygonOutline = new YMaps.Style();
stylePolygonOutline.polygonStyle = new YMaps.PolygonStyle();
stylePolygonOutline.polygonStyle.outline = true;
stylePolygonOutline.polygonStyle.strokeColor = "0000ff88";
stylePolygonOutline.polygonStyle.strokeWidth = 3;
 
// Стиль заливки многоугольника
// Наследуется от stylePolygonOutline
var stylePolygon = new YMaps.Style(stylePolygonOutline);
stylePolygon.polygonStyle = new YMaps.PolygonStyle();
stylePolygon.polygonStyle.fill = true;
stylePolygon.polygonStyle.fillColor = "0000ff33";
 
// Стиль значка метки
// Наследуется от stylePolygon
var styleIcon = new YMaps.Style(stylePolygon);
styleIcon.iconStyle = new YMaps.IconStyle();
styleIcon.iconStyle.href = "http://info.maps.yandex.net/api/i/steelblue/dot.png";
styleIcon.iconStyle.size = new YMaps.Point(26, 46);
styleIcon.iconStyle.offset = new YMaps.Point(-22, -46);

Теперь если применить третий стиль (styleIcon) к группе, состоящей из метки и многоугольника, то внешний вид обоих объектов будет изменен:

// Создание группы с заданным стилем для значка метки и многоугольника
var group = new YMaps.GeoObjectCollection(styleIcon);
group.add([
    new YMaps.Placemark(map.getCenter()),
    new YMaps.Polygon([new YMaps.GeoPoint(37.53, 55.77), new YMaps.GeoPoint(37.53, 55.83),new YMaps.GeoPoint(37.75, 55.83)])
]);
map.addOverlay(group);

Посмотреть пример в отдельном окне 

Создавать стили можно как обычные объекты Javascript, т. е. без вызова конструктора. Перепишем стиль styleIcon.

var styleIcon = {
    parentStyle : stylePolygon,
    iconStyle : {
        href : "http://info.maps.yandex.net/api/i/steelblue/dot.png",
        size : new YMaps.Point(26, 46),
        offset : new YMaps.Point(-22, -46
    }
}

В этой статье мы рассмотрели оформление меток с использованием стилей, их наследования и дополнения. Рассмотренные механизмы формирования стилей могут использоваться совместно, избавляя разработчика от необходимости многократного дублирования кода.

 
5 комментариев
Подписаться на комментарии к посту
 

Ключ – это строка, которая является уникальным идентификатором стиля.

В наименовании ключа можно использовать любые символы, однако рекомендуется создавать свое пространство имен и в нем задавать пользовательские стили.
 Относится ли рекомендация по созданию своего пространства имен к пользовательким стилям языка YMapsML, и если да, то каков синтаксис объявления ключа стиля в своем пространстве имен?
В случае YMapsML пространство имен формируется автоматически из адреса xml.
Таким образом после загрузки YMapsML в хранилище стилей будет добавлен стиль с ключом "#".

Приведу фрагмент YMapsML-документа (полный его код доступен здесь):
После загрузки YMapsML в хранилище стилей будет добавлен стиль с ключом:
http://api.yandex.ru/maps/ymapsml/examples/styleobject.xml#styleCafe

Это означает, что нужно следить, чтобы стили в пределах одного YMapsML-документа были уникальными
Подскажите пожалуйста, ато в доке не совсем понял. А для чего нужен Template? Для задания кода вывода элемента, а не только его стиля? или нет
В стили вынесены общие свойства: цвет и ширина линии, иконка ее размер и смещение относительно точки привязки и т. д.

Если для настройки внешнего вида объекта не хватает свойств, которые доступны через стили (например, значок метки содержит не только изображение), то можно воспользоваться шаблонами.

Шаблоны - это верстка со вставками данных, т. е. Вы самостоятельно задаете полностью внешний вид, а также указываете какие данные и в какие фрагменты шаблона необходимо вставить.

В Руководстве разработчика приведен пример создания своего значка метки.

Рассмотрим другой пример. По умолчанию шаблон содержимого балуна выглядит следующим образом:
$[name]$[description]
Предположим, что необходимо в балуне для каждого объекта, размещенного на карте, выводить еще ссылку на дополнительную информацию об объекте.

Можно воспользоваться стандартным полем объектов на карте - id, в котором будет содержаться уникальный номер объекта.

Соответственно шаблон может выглядеть так:
 $[name]$[description]http://mysite.ru/content/$[id]">Подробнее
Таким образом нет необходимости для каждого объекта задавать весь html-код, а достаточно задать значения полей, которые используются в шаблоне. Это избавит Вас от проблемы дублирования кода.

Если возникнет необходимость изменить ссылку, то ее нужно будет поменять лишь в шаблоне.

А теперь напишем небольшой фрагмент кода, демонстрирующий использования шаблона, описанного выше.
// Создаем новый стиль           
var myStyle = new YMaps.Style();
myStyle.balloonContentStyle = new YMaps.BalloonContentStyle(
    new YMaps.Template("$[name]$[description]</div>http://mysite.ru/content/$[id]\">Подробнее")
);

// Создаем метку
var placemark = new YMaps.Placemark(map.getCenter(), {style : myStyle});

// Имя объекта
placemark.name = "Объект в центре карты";

// Описание объекта
placemark.description = "Координаты центра карты можно получить с помощью метода getCenter()";

// Уникальный ID объекта (по нему формируется ссылка)
placemark.id = 2009;

// Добавляем метку на карту
map.addOverlay(placemark);
Надеюсь, что теперь тема шаблонов для Вас стала более понятно.

В ближайшее время мы напишем статью про использованию шаблонов и макетов. Следите за обновлениями клуба ;)
Спасибо! примерно так и понял, теперь убедился)