[英]How can I animate a SVG who is not hard coded?
我無法為使用img
標簽導入的svg設置動畫。 我無法對svg進行硬編碼,因為我的項目在使用webpack進行預處理期間會生成它。 可悲的是,由於我不知道任何“ src”或“ href”屬性,因此似乎無法通過svg
標記獲取文件。
如何為未進行硬編碼的SVG設置動畫?
這確實取決於如何通電動畫。
基本上,有三種方法可以生成動畫SVG:
當它們的<svg>
documentElement嵌入在<img>
標記中時,它們的行為如何?
<img>
SMIL動畫。 在支持的瀏覽器中,它們將正常運行,就像未嵌入SVG一樣。
您將面臨的唯一限制是
element.click
等事件不會起作用 這兩個限制都不會影響<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><img></code> and <code><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><img></code> and <code><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頁面中,但我個人不建議這樣做:
而且由於我們在這里, <img>
中SVG的另一個局限性是它無法加載其自身標記之外的任何資源,因此所有內容都必須直接包含在其中,包括字體和光柵圖像。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.