Svg Filter 相关的几个问题

在用 Leaflet 处理 GeoJSON 格式的地理信息时,解析结果被以内联的 SVG 格式嵌入网页中。为了使地图更有质感,希望通过添加阴影获得视觉上的高低效果,尝试过程记录如下。

css

首先,<svg> 内的元素是支持 css 样式的,用法也和普通的 css 一样,可以通过 id 或 class 来套用样式,但是 svg 元素具体支持的规则和普通 DOM 元素相差很大

box-shadow

box-shadow 不支持 svg 内部的元素

filter

filterdrop-shadow 也可以制造阴影效果,但是目前只有 Edge 支持对 svg 内部元素使用

元素

<defs>
    <filter id="shadow-water">
        <feGaussianBlur out="blurOut" in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
        <feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend>
    </filter>
</defs>

<filter> 本身就是 svg 标准的一部分,也是目前兼容性最好的,为 svg 元素添加阴影的方法,但是其本身并没有提供一个直接的添加阴影的方法,上面的例子里是通过将模糊后的图像和原始图像叠加实现的

<defs> 需要放置在 <svg> 元素内

需要使用此效果的元素,需要设置属性 filter="url(#shadow-water)” 来应用

svg 元素的操作

在我的环境里,svg 是由 leaflet 生成的,因此自定义的 <defs> 只能通过代码动态的插入到已有的 <svg> 标签内,但是这里不能使用 jQuery 来操作,类似

$('svg').prepend('<defs> <filter id="shadow-water"> <feGaussianBlur out="blurOut" in="SourceGraphic" stdDeviation="5"></feGaussianBlur> <feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend> </filter> </defs>');

是行不通的,因为 <svg> 内的元素类型需要是 SVGElement 才能正常工作,而 jQuery 会将 defs 等元素当作普通 DOM 元素加入到 svg 内部,因此会出现从调试工具里看到代码和手动编写的 svg 文件一致,但实际上无法发挥作用的情况。

这里有一篇文章描述了这个问题,并提供了一个动态创建 svg 元素的方法

两个 svg 标签

但是上面提到的方法写起来比较麻烦,尤其是需要动态插入的标签数量比较多,并且有嵌套的情况。

最后我尝试了将 defs 写在另一 svg 里来解决这个问题。一个 svg 里的元素是可以引用另一个 svg 里的 filter 的,我预先创建了一个只包含 defs 的 svg 标签,内部只包含了几个需要用到的 filter 效果,而没实质性的元素。这个 svg 默认也会占据一定的屏幕空间,150x300,因此需要加上样式将其隐藏。

隐藏提供特效的 svg 标签

首先尝试 style="display: none",svg 标签被隐藏了,但是特效也一起消失;

然后尝试 style="width: 0; height: 0",特效得以保留,但仍占据了屏幕大约一行文字的高度;

最终改成 style="position: absolute; width: 0; height: 0",问题解决

更多

Quasar中的前端代码转译

使用 Quasar 时,如何完成浏览器兼容性的配置。 制定兼容范围 在进行实际配置前,首先必须确定要支持浏览器的版本,而确定浏览器版本则需要先明确业务对象的情况。 为什么不干脆把标准定的越高越好呢?比如支持100%的用户。这是因为支持率越高,可用的新语法越少,意味着更多的转译代码和 polyfill,这会带来额外的代码量,从而导致下载数据量增加,以及运行速度变慢的问题,为了0.01%影响99.99%用户的体验并增加他们的流量开销,是否合适呢?这就需要根据实际业务进行取舍和平衡。 比如我们的业务对象既有企业用户,也有公众用户,企业用户主要使用钉钉,并可对其PC浏览器进行要求,而公众用户主要使用微信。 确定常用浏览器版本 PC浏览器可以指定,那么对浏览器版本就不需要过多考虑,但是部分客户还有XP系统,那么也就确定了 Chrome 浏览内核的版本不可以超过 49; 微信用户可能在手机登录,也可能在PC登录,而PC中的微信内置是QQ浏览器9,其内核版本是 Chrome 53; 电脑端的钉钉内置浏览器已经是 Chrome 91; 手机端的话考虑到安卓手机使

By 熊立丁
浙ICP备15043004号-1