The project uses a Yandex map with many of its own tag icons. These icons are created as html markup and, depending on a number of conditions, a modifier is added to the markup (as an additional class to the html element), which slightly changes the appearance of the icon.
All parameters are written to properties and then get from there to the build function of the icon template. I like this approach with modifiers very much, because it allows you to restrict yourself to just two templates, and not a few dozen, and minimizes duplication of code.
This is how it looks like:
let placemark = factory.createClass(` <div class="map-placemark-container"> <div class="map-placemark-small" data-placemark-id="$[properties.objectId]"> <i class="icon-small icon-categories icon-categories-$[properties.categoryId]"></i> </div> </div> `, { build: function() { placemark.superclass.build.call(this); let properties = this.getData().properties, element = this.getElement().querySelector('.map-placemark-small'); if(properties.get('categoryColor')) { element.style.backgroundColor = `#${properties.get('categoryColor')}`; } if(properties.get('objectStatus')) { let status = properties.get('objectStatus'); element.classList .add('map-placemark-small_status', `map-placemark-small_status-${status}`); } And stuff like that. I would like to add another modifier that will be assigned to the objects that the mouse cursor is over (and get out when the mouse leaves the object). I have already written a mouseenter event handler, and the class is assigned to the object, but the icon itself is not redrawn.
Therefore, there are several questions:
- Is it possible to change the icon when you hover in the current decision? For example, to initiate the redrawing of the icon with the new properties inside the mouseenter? If not, how is it more intelligent to implement a change of icon when hovering? Add a selected icon to a special collection? Create a new template specifically for these elements and assign it to iconLayout when you hover?
- What is the most correct approach to the design of many diverse icons in terms of the architecture of maps?
Thank!
UPD: here is an example of how to solve the problem described. The presented code is simply monstrous (besides, I had to duplicate the entire layout of the icon in the new my # hovered-template layout, so it is doubly monstrous), I am sure that this can be done in a more elegant way. The code below is a handler function that artificially causes a redrawing of a layout for an icon when the mouse is hovering over it and restoring the previous layout and active area of the icon when the mouse leaves the object.
placemark.events.add('mouseenter', (e) => { let placemark = e.get('target'); placemark.properties.set('isHovered', true); placemark.properties.set('lastShape', placemark.options.get('iconShape')); placemark.properties.set('lastTemplate', placemark.options.get('iconLayout')); placemark.options.set('iconLayout', 'my#hovered-placemark'); placemark.options.set('iconShape', { type: 'Rectangle', coordinates: [[-25, -25], [25, 25]] }); }); placemark.events.add('mouseleave', (e) => { let placemark = e.get('target'); placemark.options.set('iconLayout', placemark.properties.get('lastTemplate')); placemark.options.set('iconShape', placemark.properties.get('lastShape')); placemark.properties.unset(['lastShape', 'lastTemplate', 'isHovered']); });