SVG地图hover时阴影未贴合元素轮廓,部分国家边框阴影缺失
问题原因
- SVG元素层叠规则限制:SVG内部子元素的层叠顺序完全由其在DOM中的出现顺序决定,后定义的元素会默认覆盖在先定义的元素上层。而CSS的
z-index属性对SVG内部原生元素不生效,你代码中给.shadow类设置的z-index: 999不会产生任何作用。 - 上层元素遮挡阴影:当你给先渲染的国家路径添加阴影时,阴影延伸到后渲染的邻国区域的部分,会被上层的邻国路径直接挡住,自然就出现了某一侧阴影缺失的问题。你尝试更换多个SVG文件都存在相同问题,本质就是所有SVG地图的国家路径都有固定的渲染先后顺序,必然存在层级覆盖的情况。
解决方案
最简单的方案是在选中某国家时,将对应的路径元素移动到SVG的所有子元素末尾,让它成为最高层级的元素,阴影就不会被其他国家遮挡。你只需要修改toggle_highlight方法,在给元素设置高亮属性后增加一行移动元素的逻辑即可:
impl Country { fn toggle_highlight(e: MouseEvent, enable: bool) { let style = if enable { "#fcecec" } else { "#ececec" }; let class = if enable { "country shadow" } else { "country" }; e.target() .and_then(|t| t.dyn_into::<SvgElement>().ok()) .map(|el| { el.set_attribute("fill", style) .expect("Unable to set style attribute for the country path"); el.set_attribute("class", class) .expect("Unable to set class attribute for the country path"); // 新增逻辑:高亮时将当前国家移到最上层 if enable { if let Some(parent) = el.parent_element() { let _ = parent.append_child(&el); } } }); } }
注:DOM的
append_child方法如果传入已存在于父节点下的元素,会自动将该元素从原有位置移动到父节点的末尾,不会重复创建元素,也不会影响Yew的渲染逻辑。
如果你的地图存在国家边界重复叠加的问题,还可以适当调整drop-shadow的模糊半径,或者给高亮的国家额外增加1px的同色系描边,进一步提升边界显示效果。
内容的提问来源于stack exchange,提问作者kasom
相关产品推荐
相关产品推荐

