0

I've created an animation with CSS and an SVG, I'm having different parts of it animate in and out. I want to have it start from the top once it's done.

I have multiple keyframes, since i'm animating different parts of the SVG, and different styles of the animation.

-- I want to repeat the string of animations after they've all ran through.

This is what I have right now: https://codepen.io/megan24689/pen/NZyOdb?editors=1100 (pls check out the animation I have so far)

CSS

    .swing-out-right-fwd-1 {
    -webkit-animation: swing-out-right-fwd 0.75s cubic-bezier(0.600, -0.280, 0.735, 0.045) 2s both;
            animation: swing-out-right-fwd 0.75s cubic-bezier(0.600, -0.280, 0.735, 0.045) 2s both;
}
    .swing-in-right-fwd-2 {
        -webkit-animation: swing-in-right-fwd 0.6s cubic-bezier(0.175, 0.885, 0.320, 1.275) 3.3s both;
                animation: swing-in-right-fwd 0.6s cubic-bezier(0.175, 0.885, 0.320, 1.275) 3.3s both;
    }
    .swing-out-bottom-bck-3 {
        -webkit-animation: swing-out-bottom-bck 0.65s cubic-bezier(0.600, -0.280, 0.735, 0.045) 4.6s both;
                animation: swing-out-bottom-bck 0.65s cubic-bezier(0.600, -0.280, 0.735, 0.045) 4.6s both;
    }
    .swing-in-bottom-bck-4 {
        -webkit-animation: swing-in-bottom-bck 0.6s cubic-bezier(0.175, 0.885, 0.320, 1.275) 6s both;
                animation: swing-in-bottom-bck 0.6s cubic-bezier(0.175, 0.885, 0.320, 1.275) 6s both;
    }
    .swing-in-top-fwd-5 {
        -webkit-animation: swing-in-top-fwd 0.7s cubic-bezier(0.175, 0.885, 0.320, 1.275) 8s both;
                animation: swing-in-top-fwd 0.7s cubic-bezier(0.175, 0.885, 0.320, 1.275) 8s both;
    }
    .swing-out-left-fwd-6 {
        -webkit-animation: swing-out-left-fwd 0.55s cubic-bezier(0.600, -0.280, 0.735, 0.045) 7s both;
                animation: swing-out-left-fwd 0.55s cubic-bezier(0.600, -0.280, 0.735, 0.045) 7s both;
    }
    .swing-out-top-bck-7 {
        -webkit-animation: swing-out-top-bck 0.75s cubic-bezier(0.600, -0.280, 0.735, 0.045) 8.3s both;
                animation: swing-out-top-bck 0.75s cubic-bezier(0.600, -0.280, 0.735, 0.045) 8.3s both;
    }
    .swing-in-top-bck-8 {
        -webkit-animation: swing-in-top-bck 0.6s cubic-bezier(0.175, 0.885, 0.320, 1.275) 9.7s both;
                animation: swing-in-top-bck 0.6s cubic-bezier(0.175, 0.885, 0.320, 1.275) 9.7s both;
    }

    @-webkit-keyframes swing-out-right-fwd {
      0% {
        -webkit-transform: rotateY(0);
                transform: rotateY(0);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateY(70deg);
                transform: rotateY(70deg);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 0;
      }
    }
    @keyframes swing-out-right-fwd {
      0% {
        -webkit-transform: rotateY(0);
                transform: rotateY(0);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateY(70deg);
                transform: rotateY(70deg);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 0;
      }
    }
    @-webkit-keyframes swing-in-right-fwd {
      0% {
        -webkit-transform: rotateY(-100deg);
                transform: rotateY(-100deg);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateY(0);
                transform: rotateY(0);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 1;
      }
    }
    @keyframes swing-in-right-fwd {
      0% {
        -webkit-transform: rotateY(-100deg);
                transform: rotateY(-100deg);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateY(0);
                transform: rotateY(0);
        -webkit-transform-origin: right;
                transform-origin: right;
        opacity: 1;
      }
    }
    @-webkit-keyframes swing-out-bottom-bck {
      0% {
        -webkit-transform: rotateX(0);
                transform: rotateX(0);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateX(100deg);
                transform: rotateX(100deg);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 0;
      }
    }
    @keyframes swing-out-bottom-bck {
      0% {
        -webkit-transform: rotateX(0);
                transform: rotateX(0);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateX(100deg);
                transform: rotateX(100deg);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 0;
      }
    }

    @-webkit-keyframes swing-in-bottom-bck {
      0% {
        -webkit-transform: rotateX(-70deg);
                transform: rotateX(-70deg);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateX(0);
                transform: rotateX(0);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 1;
      }
    }
    @keyframes swing-in-bottom-bck {
      0% {
        -webkit-transform: rotateX(-70deg);
                transform: rotateX(-70deg);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateX(0);
                transform: rotateX(0);
        -webkit-transform-origin: bottom;
                transform-origin: bottom;
        opacity: 1;
      }
    }
    @-webkit-keyframes swing-in-top-fwd {
      0% {
        -webkit-transform: rotateX(-100deg);
                transform: rotateX(-100deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateX(0deg);
                transform: rotateX(0deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 1;
      }
    }
    @keyframes swing-in-top-fwd {
      0% {
        -webkit-transform: rotateX(-100deg);
                transform: rotateX(-100deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateX(0deg);
                transform: rotateX(0deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 1;
      }
    }
    @-webkit-keyframes swing-out-left-fwd {
      0% {
        -webkit-transform: rotateY(0);
                transform: rotateY(0);
        -webkit-transform-origin: left;
                transform-origin: left;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateY(-70deg);
                transform: rotateY(-70deg);
        -webkit-transform-origin: left;
                transform-origin: left;
        opacity: 0;
      }
    }
    @keyframes swing-out-left-fwd {
      0% {
        -webkit-transform: rotateY(0);
                transform: rotateY(0);
        -webkit-transform-origin: left;
                transform-origin: left;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateY(-70deg);
                transform: rotateY(-70deg);
        -webkit-transform-origin: left;
                transform-origin: left;
        opacity: 0;
      }
    }
    @-webkit-keyframes swing-out-top-bck {
      0% {
        -webkit-transform: rotateX(0deg);
                transform: rotateX(0deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateX(-100deg);
                transform: rotateX(-100deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 0;
      }
    }
    @keyframes swing-out-top-bck {
      0% {
        -webkit-transform: rotateX(0deg);
                transform: rotateX(0deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 1;
      }
      100% {
        -webkit-transform: rotateX(-100deg);
                transform: rotateX(-100deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 0;
      }
    }
    @-webkit-keyframes swing-in-top-bck {
      0% {
        -webkit-transform: rotateX(70deg);
                transform: rotateX(70deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateX(0deg);
                transform: rotateX(0deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 1;
      }
    }
    @keyframes swing-in-top-bck {
      0% {
        -webkit-transform: rotateX(70deg);
                transform: rotateX(70deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 0;
      }
      100% {
        -webkit-transform: rotateX(0deg);
                transform: rotateX(0deg);
        -webkit-transform-origin: top;
                transform-origin: top;
        opacity: 1;
      }
    }

1 Answers1

1

You could make all the animations the same duration and control their timings using percentages rather than animation-delay. This way using infinite will repeat all of them the same way.

A possible way to do that easily would be to use either JavaScript or a preprocessor. Here is an example using Sass (SCSS). This should also let you easily tweak the values of your animation to get the exact result you want. In this example, each group of values in $timings represents in this order: start time, duration, timing function, transform origin, start angle and final angle.

$duration: 10.5s;
$bezier1: cubic-bezier(0.600, -0.280, 0.735, 0.045);
$bezier2: cubic-bezier(0.175,  0.885, 0.320, 1.275);
$timings:
    2.0s .75s $bezier1 right     0deg   70deg,
    3.3s .60s $bezier2 right  -100deg    0deg,
    4.6s .65s $bezier1 bottom    0deg  100deg,
    6.0s .60s $bezier2 bottom  -70deg    0deg,
    7.0s .55s $bezier1 left      0deg  -70deg,
    8.0s .70s $bezier2 top    -100deg    0deg,
    8.3s .75s $bezier1 top       0deg -100deg,
    9.7s .60s $bezier2 top      70deg    0deg;

@for $i from 1 through length($timings) {
    $data: nth($timings, $i);
    $from: 100% * nth($data, 1) / $duration;
    $to: 100% * (nth($data, 1) + nth($data, 2)) / $duration;
    $transform: rotate#{if(nth($data, 4) == left or nth($data, 4) == right, Y, X)};
    @keyframes anim-#{$i} {
        from, #{$from} {
            transform: #{$transform}#{'('}nth($data, 5)#{')'};
            opacity: if(nth($data, 5) == 0deg, 1, 0);
        }
        #{$to}, to {
            transform: #{$transform}#{'('}nth($data, 6)#{')'};
            opacity: if(nth($data, 6) == 0deg, 1, 0);
        }
    }
    .anim-#{$i} {
        transform-origin: nth($data, 4);
        animation: anim-#{$i} $duration nth($data, 3) infinite alternate;
    }
}

Codepen fork

Note: to improve readability I also included prefixfree and got rid of the prefixed versions.

If you don't want to use a preprocessor on your side, you can just grab the generated CSS from Codepen directly ("View Compiled CSS" in the dropdown of the CSS area) or another online tool.

Bali Balo
  • 3,338
  • 1
  • 18
  • 35