首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SVG用Javascript平滑变形成其他预定义的形状

SVG用Javascript平滑变形成其他预定义的形状
EN

Stack Overflow用户
提问于 2016-05-14 10:43:29
回答 2查看 1.1K关注 0票数 1
  • 我想要形状之间的平稳转换(下面的例子显示了一个突然的转换,这样您就可以了解到我需要一个平稳的转换)。
  • 形状的顺序由Javascript决定(例如,我固定了一个任意序列,但在实际问题中,用户输入决定选择哪个形状,因此事先不知道)。

example.svg

代码语言: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

代码语言: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.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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-15 07:38:46

就像我在这里所做的那样,将所有的值放入一个动画中会更容易。如果你没有,那么你必须启动每个后续的动画,因为上一个完成,这是可行的,但更复杂。

你将需要fakeSmile或IE/Chrome的铬石,但在火狐上没有插件的情况下,这是可以发挥的。

代码语言:javascript
复制
<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>

票数 1
EN

Stack Overflow用户

发布于 2016-05-14 15:30:34

对于<animate>,规则是这两条路径必须:

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

您的动画无法工作,因为路径不兼容:

代码语言:javascript
复制
path-0: M h v h v
path-1: M h l l v
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37225638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档