關於控制SVG描邊屬性縮放的神句vector-effect: non-scaling-stroke

泱泱發表於2019-02-28

在這篇文章不炫技,SVG+CSS3 旋轉動畫屬性就能實現的夢幻效果的黃金螺旋效果中,曾經留下過一個小尾巴,就是關於描邊屬性隨著縮放動效transform:scale()等比例縮放的問題,當時用盡了各種方法,也沒有解決,嘗試多定義一層,然後描邊屬性寫在外層,依然不能奏效,描邊依舊我行我素,這在做動效的時候,是個棘手的問題,最近準備寫一篇關於“2018草莓音樂節”宣傳視訊的動畫用SVG+CSS3來實現的文章,再一次遇到了這個問題,如果不能解決的話,效果完全不是需要的。舉個例子說明:

描邊粗細不變的放大效果
需要的效果是一個描邊的素材,從中心放大,直到擴充套件到整個畫布,縮放動效是很簡單的,按照常規的定義方式,只需要定義transform:scale()屬性的變化

@keyframes enlarge{
0%{opacity:0; transform:scale(1); transform-origin:center center}
100%{transform:scale(13); transform-origin:center center}
}
#heart{animation:enlarge 3s ease}
複製程式碼

<path id="heart" d="" /> <!--心形對應的路徑-->

這裡順便插播一個關於AI匯出SVG描邊形狀的注意事項。設計師小夥伴們都知道,在AI中,描邊是有三種型別的,內描邊,外描邊和居中描邊。只有使用居中描邊匯出的路徑才能在SVG中作為stroke描邊屬性。 還拿這個案例說明,心形對應的CSS屬性是這樣的

   stroke: #000;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 8px;
複製程式碼

但如果把描邊改成內描邊來看一下,心形圖案會匯出兩個路徑

<g>
<path d=""/> <!--心形形狀對應的路徑-->
<path d=""/> <!--黑色描邊對應的路徑-->
</g>
複製程式碼

換句話說,預設給做了一個AI做了一個“輪廓化描邊”也就是描邊轉路徑的處理。所以在AI匯出SVG時,除了特殊效果,儘量使用居中描邊。可以有效簡化程式碼量,增加程式碼的可讀性。當然,還有最重要的一點,可以控制描邊的縮放屬性,下面繼續。 加了縮放變形的動效來看一下效果

縮放動效

這等比例放大的描邊,尤其在真實案例中,因為底圖都是描邊的元素,而且描邊粗細是相等的,所以這種效果可以直接被pass掉了。怎麼辦?度娘了一下,似乎沒有人提過類似的問題,更不要提解決方法了。(由此可見,SVG+CSS3動畫不火啊)仗著一手蹩腳的英文重新搜了一下,然後在codepen上看到有人解決這個問題,試了一下,咣咣啋,就是我要的屬性啊。下面隆重出場的就是

vector-effect: non-scaling-stroke

字面直譯向量效果:描邊不縮放!! 所以,我只要把這句屬性扔到圖形的CSS屬性中

    #heart{
    vector-effect: non-scaling-stroke;
    animation:enlarge 3s ease;
    }
複製程式碼

然後看一下效果

關於控制SVG描邊屬性縮放的神句vector-effect: non-scaling-stroke
完美解決問題,描邊屬性絲毫不受縮放影響! 這裡寫成內聯CSS樣式也是可以的,比如

  <path d="" vector-effect="non-scaling-stroke"/>\
複製程式碼

當然了,作為好學的我,肯定要查一查還有沒有其他相關的設定,然後在W3C中查到了如下的解釋(而且是2013年的標準):
Sometimes it is of interest to let the outline of an object keep its original width no matter which transforms are applied to it. For example, in a map with a 2px wide line representing roads it is of interest to keep the roads 2px wide even when the user zooms into the map. To achieve this, SVG Tiny 1.2 introduces the 'vector-effect' property. Future versions of the SVG language will allow for more powerful vector effects through this property but this version restricts it to being able to specify the non-scaling stroke behavior.

'vector-effect'
Value: non-scaling-stroke | none | inherit
Initial: none
Applies to: graphics elements
Inherited: no
Percentages: N/A
Media: visual
Animatable: yes
Computed value: Specified value, except inherit

好吧,廢話太多,簡而言之,沒啥用,要麼不縮放,要麼不定義,預設縮放。各位看官手下留情莫要打人。

最後結尾,以上僅限chrome瀏覽器測試效果~~

過一段時間會更新一篇文章關於草莓音樂節宣傳視訊的,裡面會大量的用到這個屬性定義。

相關文章