简体   繁体   English

SVG多边形过渡

[英]SVG Polygon transition

I'm trying make a transition of SVG <polygon> element. 我正在尝试转换SVG <polygon>元素。

The codepen is here: http://codepen.io/anon/pen/vLQOKr codepen在这里: http ://codepen.io/anon/pen/vLQOKr

I have a polygon like this: 我有一个像这样的多边形:

<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>

Now, when I change the value of points attribute, I can see the change reflected in the browser. 现在,当我更改points属性的值时,我可以看到浏览器中反映的更改。

My goal here is to use the transition (eg transition: all 2s ease 0s ) to see the animation of this change. 我的目标是使用转换(例如transition: all 2s ease 0s )来查看此更改的动画。

Is this doable in any way? 这有可能吗?

It the attached codepen, when you click the button, the points value is being replaced but the transition animation doesn't work. 附加的codepen,当您单击按钮时, points值将被替换但transition动画不起作用。

Thanks, Karol 谢谢,卡罗尔

You can only use CSS animation on attributes that are designated as CSS "properties". 您只能在指定为CSS“属性”的属性上使用CSS动画。 points is not one of those - at least not yet. points不是其中之一 - 至少现在还没有。

You can however animate it with the SMIL animation features of SVG. 但是,您可以使用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> 

Here we are specifying three keyframes: the start, the end, and then back to the start. 这里我们指定三个关键帧:开始,结束,然后回到开始。 For the easing, there are two keySplines values, one for each direction of travel. 对于缓动,有两个keySplines值,每个值对应一个旅行方向。

Manual triggering 手动触发

If you need to be able to manually control the animation - such as per your example. 如果您需要能够手动控制动画 - 例如根据您的示例。 You can have two different <animate> elements. 您可以拥有两个不同的<animate>元素。 One for each direction. 每个方向一个。 Then you can trigger each animation by calling beginElement() . 然后,您可以通过调用beginElement()来触发每个动画。 You can find out more about that here . 你可以在这里找到更多相关信息。

IE support IE支持

Unfortunately, SMIL animation does not work in IE. 不幸的是,SMIL动画在IE中不起作用。 So you would need to use the FakeSmile JS library to add support to IE. 因此,您需要使用FakeSmile JS库来添加对IE的支持。

Or you could use one of the JS SVG libraries, like SNapJS, RaphaelJS etc. Most of them have cross-browser animation functions. 或者您可以使用其中一个JS SVG库,如SNapJS,RaphaelJS等。其中大多数都具有跨浏览器动画功能。

Or do the animation yourself :) 或者自己做动画:)

Or, of course, you could just do the interpolation of the path yourself. 或者,当然,您可以自己进行路径插值。 Instead of setting that Y coord to either 20 or 50, use a timeout or requestAnimationFrame to change it in steps. 不要将Y坐标设置为20或50,而是使用超时或requestAnimationFrame来逐步更改它。

I wouldn't recommend SMIL as it has limited support and going to be deprecated in the nearest future. 我不推荐SMIL,因为它支持有限,并且在不久的将来会被弃用。 CSS animation won't work an attributes, so JS is the only way. CSS动画不会起作用属性,所以JS是唯一的方法。 Here's an example: 这是一个例子:

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM