📜 ⬆️ ⬇️

Creating a custom map control using the Yandex.Maps API 2.0


The Rambler cards have one interesting design solution that is not found in other maps. This is the control of the center of the map, due to which the current center of the map is shown. It is with the example of this functionality that I would like to tell you how to make your control for maps on your site.

The creation of the control is divided into several stages.

Step 1. Layout.


Layout, he's the layout. This entity is responsible for the appearance of the element on the map. In our case, this is a cross, when you hover over which will show the coordinates of the center of the map. We will create the layout using the special factory templateLayoutFactory .

var CrossCenterLayout = ymaps.templateLayoutFactory.createClass('<div id="cross-center" style="left:$[options.position.left]px;top:$[options.position.top]px;">+</div>', { build: function() { CrossCenterLayout.superclass.build.call(this); this._controlListeners = this.events.group().add('mouseenter', this.onCenterEnter, this).add('mouseleave', this.onCenterLeave, this); //    ,     this._map = this.getData().map; }, clear: function() { this._controlListeners.removeAll(); CrossCenterLayout.superclass.clear.call(this); }, onCenterEnter: function() { var center = this._map.getCenter(); var lat = center[0].toFixed(2); var lng = center[1].toFixed(2); //          this._map.hint.show(center, { content: lat + ', ' + lng }); }, onCenterLeave: function() { //   this._map.hint.hide(); } }); 

Consider the code in detail. Factory templateLayoutFactory accepts 2 parameters as input, a template for the future layout and a list of methods of the new layout that can override the methods of the parent class .
In our case, we override the build and clear methods, as well as add our own onCenterEnter and onCenterLeave methods . In the build method, we add mouseleave and mouseenter subscriptions to the event manager container .
In the clear method, we get rid of these subscriptions.
')

Step 2. Class of control.


 var CrossCenter = function() { this.events = new ymaps.event.Manager(); this.options = new ymaps.option.Manager(); this.state = new ymaps.data.Manager(); }; CrossCenter.prototype = { setParent: function(parent) { this.parent = parent; if (parent) { var map = parent.getMap(); this.layout = new CrossCenterLayout({ //      ,         map: map, options: this.options }); //     pane  this.layout.setParentElement(map.panes.get('controls').getElement()); } else { this.layout.setParentElement(null); } }, getParent: function() { return this.parent; } }; 

This is probably the hardest part of the code. Here we implement the IControl interface. First, we set the required fields using the appropriate event , option, and data managers. Then we implement the setParent and getParent methods. The first one was peeped in the source code of api, thanks to the debug mode, and the second, I think, does not cause questions.

Step 3. Adding to the card


Given the style
 #cross-center{ font-size: 20px; cursor: pointer; position: absolute; z-index: 800; } 

and container card
 <div id="map" style="height: 300px; width: 420px;"></div> 

create a control and add it to the center of the map
 var crossCenter = new CrossCenter(); map.controls.add(crossCenter, { top: 140, left: 200 }); 

See the result of works.

PS In order to be just like at Rambler, you can add reverse geocoding to the onCenterEnter method by changing the parameter kind depending on the current zoom of the map.

Source: https://habr.com/ru/post/145548/


All Articles