SVG过滤器:根据浏览器的不同结果

时间:2017-09-03 10:42:47

标签: svg lighting svg-filters

我正在尝试向point light effect矩形添加SVG。问题是我得到了不同的结果取决于我使用的浏览器。例如,在Chrome和Safari中,我得到了以下内容:

enter image description here enter image description here

如何在不同的浏览器上使用svg过滤器获得一致的结果?

*, *:before, *:after {
  box-sizing: border-box;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>



<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <filter id="customPointLight">
      <feSpecularLighting result="lightBuffer" specularConstant="1.5"
          specularExponent="80" lighting-color="#fff">
        <fePointLight x="100" y="100" z="80"/>
      </feSpecularLighting>
      <feComposite in="SourceGraphic" in2="lightBuffer" operator="out"
          k1="0" k2="1" k3="1" k4="0"/>
    </filter>
  </defs>

  <rect x="50" y="50" width="100" height="100" fill="blue" filter="url(#customPointLight)"></rect>
  
</svg>

3 个答案:

答案 0 :(得分:2)

Safari正在自动选择不正确的过滤器分辨率,可能是因为没有人费心去更新视网膜显示器的代码。你可以踢Safari来做#34;主要是&#34;通过添加filterRes =&#34; 200&#34;到filter元素,因为它还没有放弃对filterRes的支持。

也就是说,今天做跨浏览器的正确方法是完全使用光源,只需使用一个矩形填充黑色/白色径向渐变作为数据导入:带有feImage的URI(适用于Firefox&amp;边缘兼容性)。屏幕混合会将白色高光添加到原始照片中,因为我认为您打算这样做。像这样:

&#13;
&#13;
svg {
background: red;
}
&#13;
<svg width="400px" height="200px" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
     <radialGradient id="lightHack">
      <stop offset="35%" stop-color="white"/>
      <stop offset="80%" stop-color="black"/>
    </radialGradient>
    
    <filter id="customPointLight">
      <feSpecularLighting result="lightBuffer" specularConstant="1.5"
          specularExponent="80" lighting-color="#fff">
        <fePointLight x="100" y="100" z="80"/>
      </feSpecularLighting>
      <feComposite in="SourceGraphic" in2="lightBuffer" operator="out"
          k1="0" k2="1" k3="1" k4="0"/>
    </filter>
    
    <filter id="pointLightHack" x="0%" y="0%" width="100%" height="100%">
       <feImage width="100" height="100" xlink:href="data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwMCAxMDAiDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KDQogIDxkZWZzPg0KICAgIDxyYWRpYWxHcmFkaWVudCBpZD0iZXhhbXBsZUdyYWRpZW50Ij4NCiAgICAgIDxzdG9wIG9mZnNldD0iNDAlIiBzdG9wLWNvbG9yPSJ3aGl0ZSIvPg0KICAgICAgPHN0b3Agb2Zmc2V0PSI3NSUiIHN0b3AtY29sb3I9ImJsYWNrIi8+DQogICAgPC9yYWRpYWxHcmFkaWVudD4NCiAgPC9kZWZzPg0KICA8Y2lyY2xlIGZpbGw9InVybCgjZXhhbXBsZUdyYWRpZW50KSIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8L3N2Zz4="/>
      <feBlend mode="screen" in="SourceGraphic"/>
    </filter>
  </defs>

  <rect x="50" y="50" width="100" height="100" fill="blue" filter="url(#customPointLight)"/>
  <rect x="250" y="50" height="100" width="100" fill="blue" filter="url(#pointLightHack)"/>
</svg>

  <!-- SVG source of the base64 encoded feImage -->

  <svg width="100" height="100" viewBox="0 0 100 100"
   xmlns="http://www.w3.org/2000/svg">

  <defs>
    <radialGradient id="exampleGradient">
      <stop offset="40%" stop-color="white"/>
      <stop offset="75%" stop-color="black"/>
    </radialGradient>
  </defs>
  <circle fill="url(#exampleGradient)" cx="50" cy="50" r="50"/>
</svg>
&#13;
&#13;
&#13;

顺便说一句,你没有正确使用灯光效果,镜面灯应该添加&#34;闪亮&#34;突出显示,因此正确的用法是将结果合成在源代码之上。漫射照明应该添加&#34;常规&#34;光线应该与原始图形相乘。在任何情况下,你都不应该使用&#34; out&#34;复合操作 - 在矩形中打孔透明孔,如上面添加红色背景时所示。

答案 1 :(得分:1)

对于在计算中使用相邻像素的所有过滤器,例如feSpecularLightingfeGaussianBlurfeConvolveMatrix,结果受属性filterRes的影响,属性feSpecularLighting定义了计算滤镜效果。与其他属性不同,specification没有定义默认值:

  

如果未提供,则用户代理将使用合理的值在输出设备上生成高质量的结果。

这为UA之间的很多差异留下了空间。

kernelUnitLength本身有一个显式引用过滤器分辨率的属性DayOfWeek=$(date +%A)

  

对于显示媒体和用户代理之间某种程度的一致性(sic!),必须为'filterRes'中的至少一个提供值,的 'kernelUnitLength'

答案 2 :(得分:0)

现在解决了添加带有模糊基元的圆圈,这种圆圈提供了类似的效果,并且似乎可以在浏览器中正确呈现。

*, *:before, *:after {
  box-sizing: border-box;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="4"></feGaussianBlur>
    </filter>
  </defs>

  <rect x="50" y="50" width="100" height="100" fill="blue""></rect>
  <circle cx="100" cy="100" r="20" fill="#fff" filter="url(#blur)"></circle>	
  
</svg>