diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f94b303 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,59 @@ +# jQuery.ddMap changelog + + +## Version 2.0 (2023-05-22) +* \* The library has been renamed from `ddYMap` to `ddMap`: `jQuery.fn.ddYMap` → `jQuery.fn.ddMap`. +* \+ You may not to think about including Yandex Map script, the library will do it automatically. +* \+ The map size will be automatically updated each time the `resize` event will be triggered on the main container. +* \+ All children of the main element will be deleted during initialisation. +* \+ If Yandex Map API is not loaded, the script will await it. +* \* Parameters: + * \+ `params.apiKey`: The new parameter. Yandex Maps API key. For now it is working without key, but Yandex mark it as required, so it is recommended to set it. + * \* The following have been renamed: + * \* `params.placemarks` → `params.markers`. + * \* `params.placemarkOptions` → `params.markerOptions`. + * \- `params.zoom`, `params.latLng`: The outdated names are no longer supported, use `params.defaultZoom` and `params.placemarks` instead. +* \+ Events → `ddBeforeInit`: The new event. +* \+ README, README_ru. +* \+ CHANGELOG, CHANGELOG_ru. +* \* Attention! Backward compatibility is broken. + + +## Version 1.4 (2015-07-23) +* \+ Parameters → `controls`: The new optional parameter. It is an array of controls to be added onto the map. +* \+ Parameters → `mapOptions`: The new optional parameter. It represents yandex map [options](https://tech.yandex.com/maps/doc/jsapi/2.1/ref/reference/Map-docpage/#param-options) to be passed to the constructor. + + +## Version 1.3.1 (2014-07-24) +* \* Hidden map with the several placemarks will be positioned on the first show. +* \* Empty height of the map element will be set to `400px`. + + +## Version 1.3 (2014-07-10) +* \* **Be advised!** The [2.1](http://api.yandex.ru/maps/api21.xml) version of Yandex Maps API is used! +* \+ The new `geolocation` and `full screen` controls have been added onto map. +* \* Parameters → `placemarks`: + * \* The parameter has been renamed from `latLng` (the old name is still can be used, but it's recommended to use the new one). + * \+ Now can be either an array of placemarks or a pair of coordinates. Each placemark can have its position as well as a tip that appears when clicked. The parameter can be, as before, a coordinate pair for the map center. +* \+ The map object (an instance of `ymaps.Map`) is now stored inside of the 'ddYmap' property of the map container (the one that `jQuery.fn.ddYMap` is applied to) via the jQuery.fn.data method of JQuery. +* \+ Events → `ddAfterInit`: The new event. It's attached to the map container and will be triggered after the map has been initialized. + + +## Version 1.2 (2014-06-05) +* \+ Parameters → `mapCenterOffset`: The new optional parameter. It allows center offset of the map to be set in pixels with respect to the center of the map container. +* \* Parameters → `defaultZoom`: The parameter has been renamed from `zoom` (the old name is still can be used, but it's recommended to use the new one). + + +## Version 1.1 (2014-03-16) +* \+ The `jQuery.fn.ddYMap` method has been added. The internal method `jQuery.ddYMap.init` is not recommended to use. +* \+ The `params.defaultType` parameter which allows to set default map type has been added. +* \- The redundant parameter `params.elementId` has been removed. +* \* The internal variable `elementId` has been ranamed as `element`. + + +## Version 1.0 (2013-07-12) +* \+ The first release. + + + + \ No newline at end of file diff --git a/CHANGELOG_ru.md b/CHANGELOG_ru.md new file mode 100644 index 0000000..de37293 --- /dev/null +++ b/CHANGELOG_ru.md @@ -0,0 +1,59 @@ +# jQuery.ddMap changelog + + +## Версия 2.0 (2023-05-22) +* \* Библиотека переименована из `ddYMap` в `ddMap`: `jQuery.fn.ddYMap` → `jQuery.fn.ddMap`. +* \+ Можно не думать о подключении скрипта Яндекс Карт, библиотека сделает это автоматически. +* \+ Размер карты будет автоматически обновляться при каждом срабатывании события `resize` на главном контейнере. +* \+ Все дочерние элементы главного элемента будут удалены во время инициализации. +* \+ Скрипт будет дожидаться загрузки API Яндекс Карт по необходимости. +* \* Параметры: + * \+ `params.apiKey`: Новый параметр. API-ключ Яндекс Карт. Пока что работает и без ключа, но Яндекс декларирует его обязательным, так что рекомендуется использовать. + * \* Следующие переименованы: + * \* `params.placemarks` → `params.markers`. + * \* `params.placemarkOptions` → `params.markerOptions`. + * \- `params.zoom`, `params.latLng`: Устаревшие названия больше не поддерживаются, используйте вместо них `params.defaultZoom` и `params.placemarks`. +* \+ Событие → `ddBeforeInit`: Новое событие. +* \+ README, README_ru. +* \+ CHANGELOG, CHANGELOG_ru. +* \* Внимание! Обратная совместимость нарушена. + + +## Версия 1.4 (2015-07-23) +* \+ Параметры → `controls`: Новый необязательный параметр. Массив элементов управления картой. +* \+ Параметры → `mapOptions`: Новый необязательный параметр. [Опции карты](https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Map-docpage/#param-options), которые будут переданы в конструктор. + + +## Версия 1.3.1 (2014-07-24) +* \* Если меток несколько и карта изначально скрыта, то позиционирование делается при первом показе. +* \* Если у элемента с картой не задана высота, она выставляется в `400px`. + + +## Версия 1.3 (2014-07-10) +* \* **Внимание!** Используется API Яндекс Карт версии [2.1](http://api.yandex.ru/maps/api21.xml)! +* \+ Добавлены новые элементы управления на карту: геолокация и полноэкранный режим. +* \* Параметры → `placemarks`: + * \* Параметр переименован из `latLng` (старое имя пока поддерживается, но не рекомендуется к использованию). + * \+ Теперь принимает массив меток, а не просто пару координат. У каждой метки можно задать не только позицию, но и всплывающую при клике подсказку (балун). Параметр, как и раньше, может принимать и просто пару координат центра карты. +* \+ Объект карты (экземпляр `ymaps.Map`) записывается в data 'ddYMap' контейнеру с картой (к которому применён `jQuery.fn.ddYMap`). +* \+ События → `ddAfterInit`: Новое событие. Вызывается у контейнера с картой после инициализации. + + +## Версия 1.2 (2014-06-05) +* \+ Параметры → `mapCenterOffset`: Новый необязательный параметр. Позволяет задать смещение центра карты относительно центра контейнера в пикселях. +* \* Параметры → `defaultZoom`: Параметр переименован из `zoom` (старое имя пока поддерживается, но не рекомендуется к использованию). + + +## Версия 1.1 (2014-03-16) +* \+ Добавлен метод `jQuery.fn.ddYMap`, внутренний метод `jQuery.ddYMap.init` не рекомендуется к использованию. +* \+ Добавлен параметр `params.defaultType`, позволяющий задать тип карты по умолчанию. +* \- Параметр `params.elementId` удалён за ненадобностью. +* \* Внутренняя переменная `elementId` переименована в `element`. + + +## Версия 1.0 (2013-07-12) +* \+ Первый релиз. + + + + \ No newline at end of file diff --git a/README.md b/README.md index d46aefa..3640910 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,163 @@ -# jQuery.ddYMap +# jQuery.ddMap -A jQuery library that allows Yandex.Maps to be rendered on a page in a simple way. -___ -Visit the following [link](http://code.divandesign.biz/jquery/ddymap) to read the documentation, instructions & changelog. \ No newline at end of file +A jQuery library that allows Yandex Maps to be rendered on a page in a simple way. + +Right now the library works only with Yandex Maps, but in the future we are likely to add Google Maps and OpenStreetMap as well. + +Features: +* You may not to think about including Yandex Map script, the library will do it automatically. +* You don't even have to worry about the container size, the lib will set default size if it is zero. +* If more than one marker is used, the map will be automatically scaled so that all markers are visible. +* The map size will be automatically updated each time the `resize` event will be triggered on the main container. + + +## Requires + +* [jQuery](https://jquery.com/) >= 3.5.0 (not tested with older versions) +* [Yandex Maps JS API](https://yandex.com/dev/maps/jsapi/doc/2.1/) => 2.1 (will be included automatically if missing on a page) + + +## Usage + + +### 1. Include JS on page + +```html + + + + + +``` + +You may not to think about including Yandex Map script, the library will do it automatically. + + +### 2. Add a map container wherever you like on a page + +```html + +
+ +``` + +You don't even have to worry about the container size, the lib will set default size if it is zero. + + +### 3. Run `jQuery.fn.ddMap` + +```js +$('.map').ddMap({ + //You can add several markers if you want + //If there is more than one marker, the map will be auto-scaled to make all the markers visible + markers: [ + //At least one marker is required + { + //Geo position is required + latLng: [ + 51.532098, + -0.178100 + ], + //Content is optional, you can avoid it + content: '

Some marker text.

' + } + ] +}); +``` + +That's all! + + +## Parameters description + + +### `jQuery.fn.ddMap(params)` + +* `params` + * Desctription: The parameters. + * Valid values: `objectPlain` + * **Required** + +* `params.markers` + * Desctription: Array of markers to be put on the map. + * If there is more than one marker, the map will be auto-scaled to make all the markers visible. + * Also, a pair of coordinates still can be passed (like it was in 1.2 and earlier). + * Valid values: `array` + * **Required** + +* `params.markers[i]` + * Desctription: A marker data. + * Valid values: `objectPlain` + * **Required** + +* `params.markers[i].latLng` + * Desctription: Marker coordinates (latitude and longitude). + * Valid values: `array` + * **Required** + +* `params.markers[i].content` + * Desctription: Content of marker popup. HTML tags are supported. + * Valid values: `string` + * Default value: `''` + +* `params.apiKey` + * Desctription: Yandex Maps API key. + _For now it is working without key, but Yandex mark it as required, so it is recommended to set it._ + * Valid values: `string` + * Default value: — + +* `params.defaultZoom` + * Desctription: Default map zoom. + * Valid values: `integer` + * Default value: `15` + +* `params.defaultType` + * Desctription: Default map type. + * Valid values: + * `'map'` — schematic map + * `'satellite'` — satellite map + * `'hybrid'` — hybrid map + * Default value: `'map'` + +* `params.scrollZoom` + * Desctription: Allow zoom by mouse wheel. + * Valid values: `boolean` + * Default value: `false` + +* `params.mapCenterOffset` + * Desctription: Center offset of the map with respect to the center of the map container in pixels. + * Valid values: `array` + * Default value: `[0, 0]` + +* `params.markerOptions` + * Desctription: Marker options. + * Valid values: `objectPlain` + * Default value: `{}` + +* `params.controls` + * Desctription: An array of controls to be added onto the map. + * Valid values: `array` + * Default value: `[{name: 'zoomControl'},{name: 'typeSelector'},{name: 'fullscreenControl'},{name: 'geolocationControl'},{name: 'rulerControl'}]` + +* `params.mapOptions` + * Desctription: Represents Yandex map options to be passed to the constructor. + * Valid values: `objectPlain` + * Default value: `{suppressMapOpenBlock: true}` + + +## Events description + +All events are triggered at the main element to which `jQuery.fn.ddMap` has been applied. + +* `ddBeforeInit` — Before initialisation (when the map API is ready, immediately before the map constructor is called). +* `ddAfterInit` — After initialisation. + + +## Links + +* [Home page](https://code.divandesign.ru/jquery/ddmap) +* [Telegram chat](https://t.me/dd_code) +* [GitHub](https://github.com/DivanDesign/jQuery.ddMap) + + + \ No newline at end of file diff --git a/README_ru.md b/README_ru.md new file mode 100644 index 0000000..5b2365a --- /dev/null +++ b/README_ru.md @@ -0,0 +1,162 @@ +# jQuery.ddMap + +Библиотека jQuery, позволяющая подключить и использовать интерактивную карту на странице простым способом. + +Сейчас работает только с Яндекс Картами, но в будущем, вероятно, добавим также Google Maps и OpenStreetMap. + +Фичи: +* Можно не думать о подключении скрипта Яндекс Карт, библиотека сделает это автоматически. +* Вам даже не нужно беспокоиться о размере контейнера, библиотека поставит размер по умолчанию, если он нулевой. +* Если используется более одного маркера, карта будет автоматически масштабироваться, чтобы все маркеры были видны. +* Размер карты будет автоматически обновляться при каждом срабатывании события `resize` на главном контейнере. + + +## Использует + +* [jQuery](https://jquery.com/) >= 3.5.0 (не тестировался с более ранними версиями) +* [JS API Яндекс Карт](https://yandex.ru/dev/maps/jsapi/doc/2.1/) >= 2.1 (подключится автоматически, если отсутствует на странице) + + +## Usage + + +### 1. Подключаем JS на странице + +```html + + + + + +``` + +Можно не думать о подключении скрипта Яндекс Карт, библиотека сделает это автоматически. + + +### 2. Добавляем контейнер карты в любое удобное место на странице + +```html + +
+ +``` + +Вам даже не нужно беспокоиться о размере контейнера, библиотека поставит размер по умолчанию, если он нулевой. + + +### 3. Запускаем `jQuery.fn.ddMap` + +```js +$('.map').ddMap({ + //Маркеров на карту можно добавить несколько + markers: [ + //Как минимум один обязателен + { + //Координаты обязательны + latLng: [ + 51.532098, + -0.178100 + ], + //Контент опционален, можно опустить + content: '

Some marker text.

' + } + ] +}); +``` + +Вот и всё! + + +## Описание параметров + + +### `jQuery.fn.ddMap(params)` + +* `params` + * Описание: Параметры. + * Допустимые значения: `objectPlain` + * **Обязателен** + +* `params.markers` + * Описание: Массив маркеров для размещения на карте. + * Если задать несколько маркеров, карта будет автоматически смаштабирована, чтобы они все были видны. + * Кроме того, вместо массива маркеров по-прежнему можно передавать простую пару координат (как это было в 1.2 и более ранних версиях). + * Допустимые значения: `array` + * **Обязателен** + +* `params.markers[i]` + * Описание: Данные маркера. + * Допустимые значения: `objectPlain` + * **Обязателен** + +* `params.markers[i].latLng` + * Описание: Координаты маркера (широта и долгота). + * Допустимые значения: `array` + * **Обязателен** + +* `params.markers[i].content` + * Описание: Содержимое всплывающего окна маркера. HTML-теги поддерживаются. + * Допустимые значения: `string` + * Значение по умолчанию: `''` + +* `params.apiKey` + * Описание: API-ключ Яндекс Карт. + _Пока что работает и без ключа, но Яндекс декларирует его обязательным, так что рекомендуется использовать._ + * Допустимые значения: `string` + * Значение по умолчанию: — + +* `params.defaultZoom` + * Описание: Дефолтный масштаб карты. + * Допустимые значения: `integer` + * Значение по умолчанию: `15` + +* `params.defaultType` + * Описание: Дефолтный тип карты. + * Допустимые значения: + * `'map'` — схема + * `'satellite'` — спутник + * `'hybrid'` — гибрид + * Значение по умолчанию: `'map'` + +* `params.scrollZoom` + * Описание: Разрешить масштабирование колесом мыши? + * Допустимые значения: `boolean` + * Значение по умолчанию: `false` + +* `params.mapCenterOffset` + * Описание: Смещение центра карты относительно центра контейнера карты в пикселях. + * Допустимые значения: `array` + * Значение по умолчанию: `[0, 0]` + +* `params.markerOptions` + * Описание: Опции маркеров. + * Допустимые значения: `objectPlain` + * Значение по умолчанию: `{}` + +* `params.controls` + * Описание: Массив контролов карты. + * Допустимые значения: `array` + * Значение по умолчанию: `[{name: 'zoomControl'},{name: 'typeSelector'},{name: 'fullscreenControl'},{name: 'geolocationControl'},{name: 'rulerControl'}]` + +* `params.mapOptions` + * Описание: Опции, которые будут переданы в конструктор Яндекс карты. + * Допустимые значения: `objectPlain` + * Значение по умолчанию: `{suppressMapOpenBlock: true}` + + +## Описание событий + +Все события срабатывают на основном элементе, к которому был применен `jQuery.fn.ddMap`. + +* `ddBeforeInit` — Перед инициализацией (когда API карты готов, непосредственно перед вызовом конструктора карты). +* `ddAfterInit` — После инициализации. + + +## Ссылки + +* [Home page](https://code.divandesign.ru/jquery/ddmap) +* [Telegram chat](https://t.me/dd_code) +* [GitHub](https://github.com/DivanDesign/jQuery.ddMap) + + + \ No newline at end of file diff --git a/jQuery.ddMap.js b/jQuery.ddMap.js new file mode 100644 index 0000000..0a35f28 --- /dev/null +++ b/jQuery.ddMap.js @@ -0,0 +1,309 @@ +/** + * jQuery.ddMap + * @version 2.0 (2023-05-22) + * + * @see {@link README.md} + * + * @link https://code.divandesign.ru/jquery/ddmap + * + * @copyright 2013–2023 [Ronef]{@link https://Ronef.ru } + */ + +(function($){ + class ddMap { + static isStaticInited = false; + + static initStatic(params){ + var theClass = this; + + if (!theClass.isStaticInited){ + theClass.isStaticInited = true; + + //If Yandex Maps API is not included yet + if (typeof ymaps == 'undefined'){ + var apiSrc = '//api-maps.yandex.ru/2.1/?lang=' + navigator.language; + + if (params.apiKey.length > 0){ + apiSrc += '&apikey=' + params.apiKey; + } + + $('head').append(''); + } + } + } + + constructor(props){ + var + theInstance = this, + theClass = theInstance.constructor + ; + + theInstance.markers = new Array(); + theInstance.$element = 'map'; + theInstance.defaultZoom = 15; + theInstance.defaultType = 'map'; + theInstance.scrollZoom = false; + theInstance.mapCenterOffset = false; + theInstance.markerOptions = {}; + theInstance.controls = [ + {name: 'zoomControl'}, + {name: 'typeSelector'}, + {name: 'fullscreenControl'}, + {name: 'geolocationControl'}, + {name: 'rulerControl'} + ]; + theInstance.mapOptions = { + suppressMapOpenBlock: true + }; + + theInstance.apiConnectionAttempts = 0; + + theInstance.setProps(props); + + theClass.initStatic({ + apiKey: + typeof props.apiKey == 'undefined' ? + '' : + props.apiKey + }); + + theInstance.constructor_init(); + } + + constructor_init(){ + var theInstance = this; + + //If Yandex map API is not loaded yet + if (typeof ymaps == 'undefined'){ + theInstance.apiConnectionAttempts++; + + //Try again later but 10 attempts as maximum + if (theInstance.apiConnectionAttempts < 10){ + setTimeout( + theInstance.constructor_init.bind(theInstance), + ( + 500 + + //Await + 100 ms after each attempt + theInstance.apiConnectionAttempts * 100 + ) + ); + } + }else{ + ymaps.ready(function(){ + var + //Подготавливаем точки + geoObjects = theInstance.prepareMarkers(), + //Количество точек + geoObjects_len = geoObjects.getLength() + ; + + //Если точки заданы + if (geoObjects_len > 0){ + theInstance.$element = $(theInstance.$element); + + theInstance.$element.trigger('ddBeforeInit'); + + //Delete all children + theInstance.$element.empty(); + + //Установим высоту у элемента, если она не задана + if (theInstance.$element.height() == 0){ + theInstance.$element.height(400); + } + + //Создаём карту + var + map = new ymaps.Map( + theInstance.$element.get(0), + { + center: geoObjects.get(0).geometry.getCoordinates(), + zoom: theInstance.defaultZoom, + type: 'yandex#' + theInstance.defaultType, + controls: [] + }, + theInstance.mapOptions + ) + ; + + //Если заданы котролы + if(Array.isArray(theInstance.controls)){ + theInstance.controls.forEach( + control => + { + if(control.name){ + //Добавляем их + map.controls.add( + control.name, + control.options + ); + } + } + ); + } + + //Если зум не нужен + if (!theInstance.scrollZoom){ + //Выключим масштабирование колесом мыши (т.к. в 2.1 по умолчанию он включён) + map.behaviors.disable('scrollZoom'); + } + + //Добавляем метки на карту + map.geoObjects.add(geoObjects); + + //Если меток несколько + if (geoObjects_len > 1){ + //Если элемент с картой скрыт + if (theInstance.$element.is(':hidden')){ + //При первом изменении размера (иначе, если карта была скрыта, выйдет плохо) + map.events.once( + 'sizechange', + function(){ + //Надо, чтобы они все влезли + map.setBounds(geoObjects.getBounds()); + } + ); + }else{ + //Надо, чтобы они все влезли + map.setBounds(geoObjects.getBounds()); + } + } + + //Если нужно смещение центра карты + if ( + Array.isArray(theInstance.mapCenterOffset) && + theInstance.mapCenterOffset.length == 2 + ){ + var position = map.getGlobalPixelCenter(); + + map.setGlobalPixelCenter([ + position[0] - theInstance.mapCenterOffset[0], + position[1] - theInstance.mapCenterOffset[1] + ]); + } + + theInstance.$element + .on( + 'resize', + () => { + map.container.fitToViewport(); + } + ) + .data( + 'ddMap', + {map: map} + ) + .trigger('ddAfterInit') + ; + } + }); + } + } + + prepareMarkers(){ + var + theInstance = this, + geoObjects = new ymaps.GeoObjectCollection() + ; + + if (!Array.isArray(theInstance.markers)){ + return geoObjects; + } + + //Если передана просто пара координат + if ( + theInstance.markers.length == 2 && + $.isNumeric(theInstance.markers[0]) && + $.isNumeric(theInstance.markers[1]) + ){ + //Значит точка одна + geoObjects.add( + new ymaps.Placemark( + theInstance.markers, + {}, + theInstance.markerOptions + ) + ); + }else{ + //Переберём все точки + theInstance.markers.forEach( + markerData => { + //Если координаты заданы + if ( + $.isPlainObject(markerData) && + Array.isArray(markerData.latLng) && + markerData.latLng.length == 2 + ){ + //Создаём метку + geoObjects.add( + new ymaps.Placemark( + markerData.latLng, + { + balloonContent: + typeof markerData.content == 'string' ? + $.trim(markerData.content) : + '' + }, + theInstance.markerOptions + ) + ); + } + } + ); + } + + return geoObjects; + } + + //This method from jQuery.ddUI + /** + * @method setProps + * @version 1.1 (2023-04-22) + * + * @desc Sets the ojbect properties. + * + * @param [props] {objectPlain} — Object props values. + * @param props[propName] {mixed} — Key is property name, value is value. + * + * @returns {void} + */ + setProps(props){ + var theInstance = this; + + if ($.isPlainObject(props)){ + Object.entries(props).forEach( + ([ + propName, + propValue + ]) => + { + //If the property exists + if (typeof theInstance[propName] != 'undefined'){ + //Plain objects are extended, others are owerwrited + if ($.isPlainObject(theInstance[propName])){ + $.extend( + theInstance[propName], + propValue + ); + }else{ + theInstance[propName] = propValue; + } + } + } + ); + } + } + }; + + $.fn.ddMap = function(params){ + return $(this).each(function(){ + new ddMap( + $.extend( + params, + { + $element: this + } + ) + ) + }); + }; +})(jQuery); \ No newline at end of file diff --git a/jQuery.ddMap.min.js b/jQuery.ddMap.min.js new file mode 100644 index 0000000..c0a65d6 --- /dev/null +++ b/jQuery.ddMap.min.js @@ -0,0 +1,2 @@ +/* jQuery.ddMap v2.0 (2023-05-22) | © https://Ronef.ru */ +!function(e){class t{static isStaticInited=!1;static initStatic(t){if(!this.isStaticInited&&(this.isStaticInited=!0,"undefined"==typeof ymaps)){var n="//api-maps.yandex.ru/2.1/?lang="+navigator.language;t.apiKey.length>0&&(n+="&apikey="+t.apiKey),e("head").append('