2016-05-14 83 views
1
  • 我想要在形狀之間平滑過渡(下面的示例顯示了突然轉變,以便您可以瞭解我需要平滑過渡的想法)。
  • 形狀的順序由Javascript確定(例如,我固定了一個任意的順序,但在實際問題中,用戶輸入決定選擇哪個形狀,所以事先不知道)。

example.svgSVG使用Javascript平滑地將形狀變形爲其他預定義形狀

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="100%" height="100%" viewBox="0 0 400 400"> 
<script> 
window.animate = function(fromId, toId, next) 
{ 
    return function() 
    { 
     var elem = document.getElementById('elem'); 
     /* Here a smooth animation is supposed to happen. */ 
     elem.setAttribute('xlink:href', '#' + toId); 

     if(next) 
     { 
      window.setTimeout(next, 1000); 
     } 
    }; 
}; 

window.onload = function() 
{ 
    /* The animation order is determined by javascript. */ 
    var step3 = window.animate('path-2', 'path-1', null); 
    var step2 = window.animate('path-1', 'path-2', step3); 
    var step1 = window.animate('path-0', 'path-1', step2); 
    var step0 = window.animate('path-0', 'path-0', step1); 

    step0(); 
}; 
</script> 

<style>path{stroke:#000;}</style> 

<defs> 
<path id="path-0" style="fill:#fcc" d="M0,0 h100 v100 h-100 v-100" /> 
<path id="path-1" style="fill:#ccf" d="M0,0 h50 l50 50 l-100 50 v-100" /> 
<path id="path-2" style="fill:#cfc" d="M0,0 h150 l-50 50 l-100 50 v-100" /> 
</defs> 

<use id="elem" xlink:href="#path-0" x="150" y="150" /> 
</svg> 

據說它與<animate>某種程度上是可行的,但我不能得到它的工作。

animate.svg

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="100%" height="100%" viewBox="0 0 400 400"> 
<script> 
window.set_animation = function(animId, fromId, toId) 
{ 
    var anim = document.getElementById(animId); 
    var from = document.getElementById(fromId); 
    var to = document.getElementById(toId); 
    anim.setAttribute('from', from.getAttribute('d')); 
    anim.setAttribute('to', to.getAttribute('d')); 
}; 

window.onload = function() 
{ 
    /* The animation order is determined by javascript. */ 
    window.set_animation('anim-0', 'path-0', 'path-1'); 
    window.set_animation('anim-1', 'path-1', 'path-2'); 
    window.set_animation('anim-2', 'path-2', 'path-1'); 

    /* Can start animation only once animation steps are defined. */ 
    var anim = document.getElementById('anim-0'); 
    anim.beginElement(); 
}; 
</script> 

<style>path{stroke:#000;}</style> 

<defs> 
    <path id="path-0" style="fill:#fcc" d="M0,0 l100,0 l0,100 l-100,0 l0,-100" /> 
    <path id="path-1" style="fill:#ccf" d="M0,0 l50,0 l50,50 l-100,50 l0,-100" /> 
    <path id="path-2" style="fill:#cfc" d="M0,0 l150,0 l-50,50 l-100,50 l0,-100" /> 
</defs> 

<path id="elem" x="150" y="150" d=""> 
    <animate id="anim-0" begin="indefinite" attributeType="XML" attributeName="d" dur="2s" from="[set by javascript]" to="[set by javascript]" /> 
    <animate id="anim-1" begin="anim-1.end" attributeType="XML" attributeName="d" dur="2s" from="[set by javascript]" to="[set by javascript]" /> 
    <animate id="anim-2" begin="anim-2.end" attributeType="XML" attributeName="d" dur="2s" from="[set by javascript]" to="[set by javascript]" /> 
</path> 
</svg> 

回答

1

如我在這裏所做的那樣,將所有值放入單個動畫更容易。如果你不這樣做,那麼你必須開始每一個後續動畫,因爲前一個動畫完成,這是可行的,但更復雜。

對於IE/Chrome,您需要fakeSmileChrome SMIL shim,但是在Firefox上沒有插件的情況下播放。

<svg xmlns="http://www.w3.org/2000/svg" 
 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
 
    width="100%" height="100%" viewBox="0 0 400 400"> 
 
<script> 
 

 
function create_animation(animId, paths, attribute) 
 
{ 
 
    var anim = document.getElementById(animId); 
 
    var values = paths.map(function(item) { return document.getElementById(item).getAttribute(attribute) }).join(';'); 
 
     
 
    anim.setAttribute('values', values); 
 
} 
 

 
window.set_animation = function(animId, paths) 
 
{ 
 
    create_animation(animId, paths, 'd'); 
 
    create_animation(animId + '-colour', paths, 'fill'); 
 
}; 
 

 
window.onload = function() 
 
{ 
 
    /* The animation order is determined by javascript. */ 
 
    window.set_animation('anim-0', ['path-0', 'path-1', 'path-2']); 
 
}; 
 
</script> 
 

 
<style>path{stroke:#000;}</style> 
 

 
<defs> 
 
    <path id="path-0" fill="#fcc" d="M0,0 l100,0 l0,100 l-100,0 l0,-100" /> 
 
    <path id="path-1" fill="#ccf" d="M0,0 l50,0 l50,50 l-100,50 l0,-100" /> 
 
    <path id="path-2" fill="#cfc" d="M0,0 l150,0 l-50,50 l-100,50 l0,-100" /> 
 
</defs> 
 
    
 
<path> 
 
    <animate id='anim-0' dur="3s" attributeName='d' fill="freeze"/> 
 
    <animate id='anim-0-colour' dur="3s" attributeName='fill' fill="freeze"/> 
 
</path>

+0

我在單獨的動畫中使用了它,因爲單個動畫片段的持續時間是可變的,我知道應該可以通過'來實現,但是我不能弄清楚我應該如何實現它,如果它在一個動畫中。你可以修改你的答案,或者我應該問一個新的問題嗎? – user66554

+0

您可以使用keyTimes來實現。如果你想要更多,請提出一個新問題。 –

1

隨着<animate>的規則是,兩個路徑必須:

  1. 具有相同數目的路徑元素的
  2. 具有匹配的路徑命令

由於路徑不兼容,您的動畫將無法使用ible:

path-0: M h v h v 
path-1: M h l l v 
+0

好。我知道一些命令是不兼容的,但並不是所有命令都是('h','v'和'l'畢竟是所有行)。修正了。儘管如此,它仍然不起作用(並且我聽說過''將被丟棄?)。 – user66554

+0

是的SMIL動畫可能會被至少一些瀏覽器刪除,而不是新的Web動畫API。但是,第三方會提供polyfills來提供向後兼容性。 –