Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion folium/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -1888,7 +1888,8 @@ class CustomIcon(Icon):
* Otherwise a string will be assumed to be JSON and embedded.
* If array-like, it will be converted to PNG base64 string and embedded.
icon_size : tuple of 2 int, optional
Size of the icon image in pixels.
Size of the icon image in pixels. If not given, the image is shown
at its natural size.
icon_anchor : tuple of 2 int, optional
The coordinates of the "tip" of the icon
(relative to its top left corner).
Expand Down
13 changes: 13 additions & 0 deletions folium/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,21 @@ class Marker(MacroElement):
class SetIcon(MacroElement):
"""Set the icon of a marker after both are created."""

# Leaflet reuses the current <img> element when the new icon is also an
# image, and keeps its inline size and margins if the new icon does not
# set them. Clear them first, so an icon without `icon_size` keeps the
# natural size of its image instead of the size of the default icon.
_template = Template("""
{% macro script(this, kwargs) %}
{
const element = {{ this.marker.get_name() }}.getElement();
if (element) {
element.style.width = "";
element.style.height = "";
element.style.marginLeft = "";
element.style.marginTop = "";
}
}
{{ this.marker.get_name() }}.setIcon({{ this.icon.get_name() }});
{% endmacro %}
""")
Expand Down
18 changes: 18 additions & 0 deletions tests/test_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,24 @@ def test_marker_numpy_array_as_location():
Marker(np.array([0, 0]))


def test_set_icon_clears_size_of_previous_icon():
# Leaflet reuses the <img> of the default icon, so its inline size must be
# cleared for a custom icon without icon_size to keep its natural size.
from folium.features import CustomIcon

m = Map()
marker = Marker([0, 0], icon=CustomIcon("https://example.com/logo.png"))
marker.add_to(m)
script = normalize(m.get_root().render())
element = f"{marker.get_name()}.getElement()"
set_icon = f"{marker.get_name()}.setIcon({marker.icon.get_name()});"
assert element in script
assert set_icon in script
assert script.index(element) < script.index(set_icon)
for prop in ("width", "height", "marginLeft", "marginTop"):
assert f'.style.{prop} = "";' in script


def test_icon_hex_marker_color():
with warnings.catch_warnings():
warnings.simplefilter("error")
Expand Down
Loading