【问题标题】:How to repeat keyframe animation of multiple parts of an SVG?如何重复 SVG 多个部分的关键帧动画?
【发布时间】:2019-11-12 12:21:56
【问题描述】:

我已经用 CSS 和 SVG 创建了一个动画,我让动画的不同部分进出动画。一旦完成,我想让它从顶部开始。

我有多个关键帧,因为我正在为 SVG 的不同部分以及不同样式的动画制作动画。

-- 我想在它们都跑完之后重复这串动画。

这就是我现在拥有的:https://codepen.io/megan24689/pen/NZyOdb?editors=1100(请查看我目前拥有的动画)

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

【问题讨论】:

  • 在动画中添加infinite
  • @TemaniAfif 所以,我认为这行不通,因为我希望它重复动画字符串而不是每个重复。我错了吗?
  • 您还需要调整关键帧并进行一些计算。这是一个了解如何完成的示例:stackoverflow.com/a/56683007/8620333
  • @TemaniAfif 有了这个解决方案,我能否让 SVG 的多个不同部分以不同的方式制作动画?

标签: javascript jquery css svg css-animations


【解决方案1】:

您可以使所有动画的持续时间相同,并使用百分比而不是动画延迟来控制它们的时间。这种使用无限的方式将以相同的方式重复所有这些。

一个简单的方法是使用 JavaScript 或预处理器。这是一个使用 Sass (SCSS) 的示例。这也应该让您轻松调整动画的值以获得您想要的确切结果。本例中$timings中的每组值依次表示:开始时间、持续时间、定时函数、变换原点、开始角度、结束角度。

$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

注意:为了提高可读性,我还加入了无前缀版本并去掉了前缀版本。

如果您不想使用预处理器,您可以直接从 Codepen 中获取生成的 CSS(CSS 区域下拉菜单中的“查看已编译的 CSS”)或其他在线工具。

【讨论】:

  • 非常感谢!这很棒(:
猜你喜欢
  • 2017-06-25
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
相关资源
最近更新 更多