Search code examples
svgsvg-animate

Animation Skipping to End of Desired Result


Pen: https://codepen.io/jkmg/pen/zYKqvLq

<html>
<head>
    <title></title>
    <style type="text/css">
    html,body {
        width: 100%;
        height: 100%;
        margin: 0px;
        padding: 0px;
        background-color: purple;
    }
    svg {
        height: 50px;
    }
    .playButton {
        width: 100px;
        height: 100px;
        background-color: white;
        display: inline-flex;
        position: fixed;
        top: 50%;
        left: 50%;
        margin-left: -50px;
        margin-top: -50px;
        border-radius: 200px;
        overflow: hidden;
    }
    .playButton .poscont {
        position: absolute;
        width: 100px;
        height: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .playButton .playGlyph {
        opacity: 1;
        margin-right: -5px;
    }
    </style>
</head>
<body>
    
    <span></span>
    <div class="playButton currentlyPaused">
      <div class="playGlyphPosition poscont">
      <svg class="playGlyph One" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70.83 122.58">
        
        <path id="playPath" d="M20.55,119.08a11.89,11.89,0,0,1-20.3-8.35L0,61.29.25,11.85a11.89,11.89,0,0,1,20.3-8.34l45,45a18.11,18.11,0,0,1,0,25.62Z"> 
        <animate xlink:href="#playPath"
                 begin="indefinite"
                 id="pauseAni"
                 attributeName="d"
                 dur="1s"
                 fill="freeze"
                 attributeType="XML"
                 from="M20.55,119.08a11.89,11.89,0,0,1-20.3-8.35L0,61.29.25,11.85a11.89,11.89,0,0,1,20.3-8.34l45,45a18.11,18.11,0,0,1,0,25.62Z"
                 to="M20.55,109.49c0,15-20.3,15-20.3-.06L0,60,.25,10.55c0-14.06,20.3-14.06,20.3-.06l0,36.69c.31,7.31.31,16.31,0,25.62Z"
                 />
        </path>
      </svg>
        </div>
      
    </div>

    <script type="text/javascript">
        document.querySelector(".playButton").addEventListener("click", function () {
          if (this.classList.contains("currentlyPaused")) {
            this.classList.remove("currentlyPaused"); 
            this.classList.add("currentlyPlaying");
            document.querySelector("#pauseAni").beginElement();
            document.querySelector("span").innerText += "\nAttempted to play, ani to pause.";
          }
          else { 
            this.classList.remove("currentlyPlaying");
            this.classList.add("currentlyPaused");
            // document.querySelector("#playAni").beginElement();
            // this.querySelector(".playGlyph").classList.add("playing");
            document.querySelector("span").innerText += "\nAttempted to pause, ani to play.";
          }
        
        });
            </script>

</body>
</html>

gifforreference

I'm attempting to animate a play button to a pause button and give the play button transformation to a faux line to use as an element for the pause button.

I have no idea why the animation is, animating with CSS or not, skipping to the end of the animation without actually "animating". Could someone please help me figure out what's going on?


Solution

  • I'll expand on Robert's comment.

    The SVG spec says:

    For animation, two d property values can only be interpolated smoothly when the path data strings contain have the same structure, (i.e. exactly the same number and types of path data commands which are in the same order). If an animation is specified and the lists of path data commands do not have the same structure, then the values must be interpolated using the discrete animation type.

    However your two paths do not have the same structure. The first path is:

    M 20.55,119.08
    a 11.89,11.89,0,0,1-20.3-8.35
    L 0,61.29.25,11.85
    a 11.89,11.89,0,0,1,20.3-8.34
    l 45,45
    a 18.11,18.11,0,0,1,0,25.62
    Z

    and the second is:

    M 20.55,109.49
    c 0,15-20.3,15-20.3-.06L0,60,.25,10.55
    c 0-14.06,20.3-14.06,20.3-.06l0,36.69
    c .31,7.31.31,16.31,0,25.62
    Z

    If you want to interpolate between the two paths, they'll need to have the same number and type of path commands.

    In other words, you'll need to edit one (or both) so that they match.