andrusieczko February 2016

SVG Polygon transition

I'm trying make a transition of SVG <polygon> element.

The codepen is here: 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.

My goal here is to use the transition (e.g. transition: all 2s ease 0s) to see the animation of this change.

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.

Thanks, Karol

Answers


Paul LeBeau February 2016

You can only use CSS animation on attributes that are designated as CSS "properties". points is not one of those - at least not yet.

You can however animate it with the SMIL animation features of SVG.

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

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. One for each direction. Then you can trigger each animation by calling beginElement(). You can find out more about that here.

IE support

Unfortunately, SMIL animation does not work in IE. So you would need to use the FakeSmile JS library to add support to IE.

Or you could use one of the JS SVG libraries, like SNapJS, RaphaelJS etc. Most of them have cross-browser ani


georg February 2016

I wouldn't recommend SMIL as it has limited support and going to be deprecated in the nearest future. CSS animation won't work an attributes, so JS is the only way. 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="p 

Post Status

Asked in February 2016
Viewed 1,553 times
Voted 10
Answered 2 times

Search




Leave an answer