簡體   English   中英

如何為未進行硬編碼的SVG設置動畫?

[英]How can I animate a SVG who is not hard coded?

我無法為使用img標簽導入的svg設置動畫。 我無法對svg進行硬編碼,因為我的項目在使用webpack進行預處理期間會生成它。 可悲的是,由於我不知道任何“ src”或“ href”屬性,因此似乎無法通過svg標記獲取文件。

如何為未進行硬編碼的SVG設置動畫?

這確實取決於如何通電動畫。


基本上,有三種方法可以生成動畫SVG:

  • SMIL動畫 -不幸的是,它並沒有得到廣泛的支持(但是您確實使用[svg-animate]進行了標記,因此以第一種情況為例)。
  • CSS動畫 -隨着SVG2的出現,我敢打賭這些將變得越來越普遍。
  • 基於腳本的動畫。

當它們的<svg> documentElement嵌入在<img>標記中時,它們的行為如何?


<img> SMIL動畫。

在支持的瀏覽器中,它們將正常運行,就像未嵌入SVG一樣。
您將面臨的唯一限制是

  • 您不會收到任何用戶手勢,因此element.click等事件不會起作用
  • 對於不支持SMIL動畫(IE ...)的瀏覽器,您不能回退到基於腳本的動畫。

這兩個限制都不會影響<object><embed><iframe>加載的SVG,因此如果需要,可以很好地使用它。

 var svgStr = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50"> <rect id="rect" x="-30" y="0" width="30" height="50"> <!-- this will work normally, even in an <img> --> <animate attributeType="XML" attributeName="x" from="-30" to="50" begin="0s" dur="10s" repeatCount="indefinite"/> <!-- this will not work in <img>, but will in <object>/<iframe>/<embed> --> <animate attributeType="XML" attributeName="fill" from="blue" to="red" begin="rect.click" dur="1s" repeatCount="1"/> </rect> <!-- js-based workaround won't work in <img> but will in <object>/<iframe>/<embed> --> <script src="https://cdn.rawgit.com/FakeSmile/FakeSmile/23c5ceae/smil.user.js"><\\/script> </svg>`; loadSVG(document.images[0]); loadSVG(document.querySelector('object')); function loadSVG(container) { var url = URL.createObjectURL(new Blob([svgStr], {type: 'image/svg+xml'})); container.src = container.data = url; } 
 img{ border: 1px solid green; } object{ border: 1px solid blue; } 
 <img src=""> <object></object> <div>Try to click the black rectangle in both the <code>&lt;img></code> and <code>&lt;object></code> tags. 

<img> CSS動畫。

就像SMIL動畫一樣,它們應該在支持瀏覽器的環境中工作,並且具有相同的用戶手勢限制以及相同的可能方式(使用其他容器):

 var svgStr = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50"> <rect id="rect" x="0" y="0" width="30" height="50"/> <defs> <style> #rect { /* this will work normally, even in an img */ animation: move 10s linear infinite; } #rect:hover { /* this will not work in img, but will in object/iframe/embed */ animation: move 10s linear infinite, color 1s 1; } @keyframes move { from { transform: translate(-30px, 0px); } to { transform: translate(50px, 0px); } } @keyframes color { from { fill: blue; } to { fill: red; } } </style> </defs> </svg>`; loadSVG(document.images[0]); loadSVG(document.querySelector('object')); function loadSVG(container) { var url = URL.createObjectURL(new Blob([svgStr], {type: 'image/svg+xml'})); container.src = container.data = url; } 
 img{ border: 1px solid green; } object{ border: 1px solid blue; } 
 <img src=""> <object></object> <div>Try to mouse hover the black rectangle in both the <code>&lt;img></code> and <code>&lt;object></code> tags. 

<img>基於腳本的動畫。

這些根本行不通。 <img>標簽中嵌入的SVG文檔無法編寫腳本。 要解決此問題,請使用<object><embed><iframe>元素作為容器。

 var svgStr = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50"> <rect id="rect" x="0" y="0" width="30" height="50"/> <script type="application/javascript"> // will simply never work in img var x = 0, rect = document.getElementById('rect'); function anim() { x = (x + 1) % 80; rect.setAttribute('x', x - 30); requestAnimationFrame(anim); } anim(); <\\/script> </svg>`; loadSVG(document.images[0]); loadSVG(document.querySelector('object')); function loadSVG(container) { var url = URL.createObjectURL(new Blob([svgStr], {type: 'image/svg+xml'})); container.src = container.data = url; } 
 img{ border: 1px solid green; } object{ border: 1px solid blue; } 
 <img src=""> <object></object> 


因此,基本上, <img> SVG帶有很多限制,而使用其他容器可以完全克服這些限制。
現在,每個容器都會有自己的限制:

  • <iframe>不會調整其內容的大小,默認情況下還會帶有邊框和其他一些難看的東西。
  • <object><embed>在不可見時將由webkit瀏覽器卸載( display: none ),並且不會在任何瀏覽器中進行緩存...

當然,也可以通過AJAX獲取SVG標記並將其加載到實際的HTML頁面中,但我個人不建議這樣做:

  • 您需要確保沒有重復的id元素,
  • 您需要確保所有CSS規則都足夠具體,以免影響您頁面中的其他元素,
  • 您將必須確保只加載受信任的代碼,因為腳本將運行,也就是說,您對XSS攻擊持敞開的大門。

而且由於我們在這里, <img>中SVG的另一個局限性是它無法加載其自身標記之外的任何資源,因此所有內容都必須直接包含在其中,包括字體和光柵圖像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM