2017-09-03 203 views
2

我正在嘗試將point light effect添加到SVG矩形中。問題是,根據我使用的瀏覽器,我得到了不同的結果。例如,在Chrome和Safari我得到了以下內容:SVG過濾器:取決於瀏覽器的不同結果

enter image description hereenter 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>

回答

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> \t 
 
    
 
</svg>

1

對於在它們的計算使用的相鄰像素,像feSpecularLightingfeGaussianBlurfeConvolveMatrix所有過濾器,其結果是由屬性filterRes,它定義用於計算過濾器效果的分辨率的影響。不像其他的屬性,所述specification定義沒有默認:

如果沒有提供,則用戶代理將使用合理的值,以產生所述輸出裝置上高質量的結果。

這給UA之間的差異留下了很大的空間。

feSpecularLighting本身具有屬性kernelUnitLength明確引用濾波器分辨率:(!原文如此)

爲了一致性的一些水平跨越顯示介質和用戶代理,這是必要的一個值被設置爲在'filterRes''kernelUnitLength'中的至少一個。

+1

filterRes是過時的,無論是鍍鉻不是火狐支持它了。 –

+0

那麼你現在對於一致性做什麼? – ccprog

+0

根據https://stackoverflow.com/questions/44891524/safari-trouble-positioning-svg-fespotlight-filter這是一個已知的與Safari相關的未解決的錯誤。可悲的是,目前還沒有修復。我認爲解決這個問題的唯一方法就是爲Safari編寫特定的代碼,直到bug被瀏覽器團隊修復。 – revy

2

Safari正在自動選擇不正確的濾鏡分辨率,可能是因爲沒有人打擾更新視網膜顯示器的代碼。您可以通過將filterRes =「200」添加到過濾元素來啓動Safari以「主要」做正確的事情,因爲它還沒有放棄對filterRes的支持。

這就是說,今天正確地做跨瀏覽器,就是完全打開光源,只是用一個填充有黑/白的徑向漸變的矩形作爲數據導入:帶有feImage的URI(適用於Firefox &邊緣兼容性)。屏幕混合會將白色高光添加到原始圖片上,因爲我認爲您是想要的。像這樣:

svg { 
 
background: red; 
 
}
<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>

順便說一句,你不正確地使用燈光效果,高光應該加上「閃亮」的亮點,所以正確用法是複合的結果在源頭之上。漫射照明應該添加「常規」燈光,並且應該與原始圖形相乘。在這兩種情況下,你都不應該使用「out」複合操作 - 在矩形中打一個透明的孔,正如你在上面添加紅色背景時看到的那樣。

+0

感謝您提供豐富的答案。我剛剛從Mozilla的fePointLight原始示例中看到:https://developer.mozilla.org/en-US/docs/Web/SVG/Element/fePointLight – revy

+0

我修正了Mozilla示例 - 它應該是operator =「arithmetic 「 –