SVG 多边形过渡



我正在尝试对 SVG <polygon>元素进行过渡。

代码笔在这里:http://codepen.io/anon/pen/vLQOKr

我有一个这样的多边形:

<svg width="300" height="200" viewBox="0 0 300 200"> <polygon points="0 0, 145 0, 150 20, 155 0, 300 0, 300 200, 0 200, 0 0" /> </svg>

现在,当我更改points属性的值时,我可以看到更改反映在浏览器中。

我在这里的目标是使用过渡(例如 transition: all 2s ease 0s (来查看此更改的动画。

这在任何方面可行吗?

它附加的代码笔,当您单击按钮时,points值将被替换,但transition动画不起作用。

谢谢卡罗尔

您只能在指定为 CSS "属性"的属性上使用 CSS 动画。 points不是其中之一——至少现在还不是。

但是,您可以使用 SVG 的 SMIL 动画功能对其进行动画处理。

<svg width="300" height="200" viewBox="0 0 300 200">
  <polygon points="">
    <animate attributeType="XML" attributeName="points"
             dur="2s" repeatCount="indefinite"
             values="0 0, 145 0, 150 20, 155 0, 300 0, 300 200, 0 200, 0 0;
                     0 0, 145 0, 150 50, 155 0, 300 0, 300 200, 0 200, 0 0;
                     0 0, 145 0, 150 20, 155 0, 300 0, 300 200, 0 200, 0 0"
             keyTimes="0; 0.5; 1" 
             calcMode="spline"
             keySplines=".5 0 .5 1;
                         .5 0 .5 1" />
  </polygon>
</svg>

在这里,我们指定了三个关键帧:开始、结束,然后回到起点。 对于缓和,有两个keySplines值,每个行进方向一个。

手动触发

如果您需要能够手动控制动画 - 例如根据您的示例。 您可以有两个不同的<animate>元素。每个方向一个。然后,您可以通过调用 beginElement() 来触发每个动画。您可以在此处找到更多信息。

IE 支持

不幸的是,SMIL 动画在 IE 中不起作用。因此,您需要使用FakeSmile JS库来添加对IE的支持。

或者你可以使用其中一个JS SVG库,如SNapJS,RaphaelJS等。 它们中的大多数都具有跨浏览器动画功能。

或者自己做动画:)

或者,当然,您可以自己对路径进行插值。 不要将该 Y 坐标设置为 20 或 50,而是使用超时或requestAnimationFrame分步更改它。

我不推荐 SMIL,因为它的支持有限,并且在不久的将来会被弃用。CSS动画不会对属性起作用,所以JS是唯一的方法。下面是一个示例:

var getPoints = function (isDeeper) {
    return isDeeper ?
        '0 0,  45 0, 150 150, 255 0, 300 0, 300 200, 0 200, 0 0' :
        '0 0, 145 0, 150  20, 155 0, 300 0, 300 200, 0 200, 0 0';
        
};
var pointsToObj = function (points) {
    var ps = points.match(/d+/g).map(Number),
        obj = {length: ps.length};
    ps.forEach(function (n, i) {
        obj['_' + i] = n;
    });
    return obj;
};
var objToPoints = function (obj) {
    var ps = [];
    for (var i = 0; i < obj.length; i++)
        ps.push(obj['_' + i]);
    return ps.join(' ');
};
var renderPoints = function ($element, isDeeper) {
    var dest = pointsToObj(getPoints(isDeeper)),
        src = pointsToObj($element.attr('points'));
    $(src).animate(dest, {
        step: function (now, fx) {
            src[fx.prop] = fx.now;
            $element.attr('points', objToPoints(src));
        }
    });
};
$(function () {
    var $button = $('button');
    var $element = $('svg polygon');
    var isDeeper = false;
    $button.bind('click', function () {
        isDeeper = !isDeeper;
        renderPoints($element, isDeeper);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="300" height="200" viewBox="0 0 300 200"
     xmlns="http://www.w3.org/2000/svg" version="1.1"
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <polygon points="0 0, 145 0, 150 20, 155 0, 300 0, 300 200, 0 200, 0 0"/>
</svg>
<button style="position:fixed;top:0;right:0">Click to change</button>

相关内容

  • 没有找到相关文章

最新更新