Change marker icon on mouseover/mouseout in Leaflet

iconjavascriptleafletmarkers

I have a map made with Javascript, on which there are numerous points and each one of them has a specific png marker.
I managed to display all the markers correctly with the following code:

var studios_marker = L.geoJSON(studios, {
    onEachFeature: mouse_events_studios,
    pointToLayer: function (feature, latlng){
var smallIcon = L.icon({
    iconUrl: ''+ features.properties.Name +'.png',
    iconSize: [50, 40],
    iconAnchor: [15,15]
});
        return L.marker(latlng, {icon: smallIcon});
}
}).addTo(map);

features.properties.Name is the attribute field in my GeoJSON file where the names of the points are stored.

My problem is that I need to take the var smallIcon part out of var studio_marker, as I'm going to need it for mouse actions, as followed. The aim is to change the marker to a new one when the mouse is over a given feature, and then replace it back with the original one, studioicon. But whenever I make my smallIcon stand alone, I get the error

"features is not defined"

What am I missing ?

var studioicon= L.icon({
    iconUrl: 'cinema.png',
    iconSize: [30, 30],
    iconAnchor: [15,15]
    });

var studios_marker = L.geoJSON(studios, {
    onEachFeature: mouse_events_studios,
    pointToLayer: function (feature, latlng){
        return L.marker(latlng, {icon: studioicon});
}
}).addTo(map);

var smallIcon = L.icon({
    iconUrl: ''+ features.properties.Name +'.png',
    iconSize: [50, 40],
    iconAnchor: [15,15]
});

function mouse_events_studios(feature, marker){
    marker.on('mouseover', function(alter_style){
        var leaflet_obj2 = alter_style.target;
        marker.setIcon(smallIcon);
    });
    marker.on('mouseout', function(origin_style){
        var leaflet_obj3 = origin_style.target;
        marker.setIcon(studioicon)
    })
}

Best Answer

Problem with your approach is that if you create icon outside pointToLayer function, feature.properties.Name is not defined at the time of icon creation (fact is, that your features.properties.Name wouldn't work even inside the function, since parameter name is feature, not features).

Solution is to create feature's small icon inside pointToLayer function (as you did initially), but not use it immediately, just save it for later as some custom property of the marker, let's say smallIcon (name can be any, as long it does not conflict with standard Leaflet marker properties).

So code could then look something like this:

var studioicon = L.icon({
  iconUrl: 'cinema.png',
  iconSize: [30, 30],
  iconAnchor: [15,15]
});
    
var studios_marker = L.geoJSON(studios, {
  onEachFeature: mouse_events_studios,
  pointToLayer: function (feature, latlng){
    var smallIcon = L.icon({
      iconUrl: ''+ feature.properties.Name +'.png',
      iconSize: [50, 40],
      iconAnchor: [15,15]
    });
    var marker = L.marker(latlng, {icon: studioicon});
    marker.smallIcon = smallIcon;
    return marker;
}
}).addTo(map);

function mouse_events_studios(feature, marker){
  marker.on('mouseover', function(alter_style){
    var leaflet_obj2 = alter_style.target;
    marker.setIcon(marker.smallIcon);
  });
  marker.on('mouseout', function(origin_style){
    var leaflet_obj3 = origin_style.target;
    marker.setIcon(studioicon);
  })
}