我正在尝试对 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>