扩展翻译元素的第一个动画的最终状态

时间:2015-08-26 10:57:59

标签: css css3 css-animations css-transforms

我知道这里有多次询问,但我要求为这种动画采用不同的方法。

问题:

第二个框有多个动画,尝试创建与第一个相同的效果。似乎转换属性被覆盖(因为它应该)* 。我正在尝试使用第二个动画的属性扩展第一个动画(第二个框)。试图使用animation-fill-mode: forwards但没有成功。也许我错过了一些基本的东西。是否可以使用vanilla CSS?

* Reference

  

'animation-name'属性定义了适用的动画列表。   如果是多个动画   试图修改相同的属性,然后最接近的动画   名字列表的结尾获胜。

要求:

分离move2-rightmove2-down关键帧规则,但处理相同的元素,保留第一个动画转换。如果有这种动画的替代方法,请引导我完成它。

当前输出:



.animation-1,
.animation-2 {
  width: 200px;
  height: 200px;
  display: inline-block;
  background: white;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
}
.movable-1,
.movable-2 {
  background: #41A186;
  width: 50px;
  height: 50px;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
}
.movable-1 {
  -webkit-animation-name: move1;
  animation-name: move1;
  -webkit-animation-duration: 4s;
  animation-duration: 4s;
  -webkit-animation-delay: 0s;
  animation-delay: 0s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
}
.movable-2 {
  -webkit-animation-name: move2-right, move2-down;
  animation-name: move2-right, move2-down;
  -webkit-animation-duration: 2s, 2s;
  animation-duration: 2s, 2s;
  -webkit-animation-delay: 4s, 6s;
  animation-delay: 4s, 6s;
  -webkit-animation-fill-mode: forwards, forwards;
  animation-fill-mode: forwards, forwards;
}
@-webkit-keyframes move1 {
  0% {
    -webkit-transform: translateX(0px);
    transform: translateX(0px);
  }
  50% {
    -webkit-transform: translateX(30px);
    transform: translateX(30px);
  }
  100% {
    -webkit-transform: translateX(30px) translateY(50px);
    transform: translateX(30px) translateY(50px);
  }
}
@keyframes move1 {
  0% {
    -webkit-transform: translateX(0px);
    transform: translateX(0px);
  }
  50% {
    -webkit-transform: translateX(30px);
    transform: translateX(30px);
  }
  100% {
    -webkit-transform: translateX(30px) translateY(50px);
    transform: translateX(30px) translateY(50px);
  }
}
@-webkit-keyframes move2-right {
  0% {
    -webkit-transform: translateX(0px);
    transform: translateX(0px);
  }
  50% {
    -webkit-transform: translateX(30px);
    transform: translateX(30px);
  }
  100% {
    -webkit-transform: translateX(30px);
    transform: translateX(30px);
  }
}
@keyframes move2-right {
  0% {
    -webkit-transform: translateX(0px);
    transform: translateX(0px);
  }
  50% {
    -webkit-transform: translateX(30px);
    transform: translateX(30px);
  }
  100% {
    -webkit-transform: translateX(30px);
    transform: translateX(30px);
  }
}
@-webkit-keyframes move2-down {
  0% {
    -webkit-transform: translateY(0px);
    transform: translateY(0px);
  }
  50% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
  }
  100% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
  }
}
@keyframes move2-down {
  0% {
    -webkit-transform: translateY(0px);
    transform: translateY(0px);
  }
  50% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
  }
  100% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
  }
}

<div class="animation-1">
  <div class="movable-1">1</div>
</div>
<div class="animation-2">
  <div class="movable-2">2</div>
</div>
&#13;
&#13;
&#13;

这是一个你可以玩的小提琴:JSfiddle

1 个答案:

答案 0 :(得分:4)

据我所知,纯CSS无法实现这一点,因为(正如您已经指出的那样),当我们向已经有变换的元素添加额外的变换规则时,整个变换会被重置,因为它会覆盖并且不会附加到现有的转换。

使用JS可能有可能实现,但即使在那里也很难实现,因为我们必须做到以下几点:

  • 完成第一个动画后处理animationend事件。
  • 在处理程序中,以像素为单位获取translateX(...)
  • 获取下一个动画的CSS关键帧规则,修改它们以将translateX(...)作为转换堆栈的第一部分。

注意:我认为您的案例绝对没有办法使用问题中提到的第一种方法。

实现类似效果的另一种方法是为元素的marginposition设置动画,而不是使用transform: translate()。这种方法的一个主要缺点是,这不会在GPU层完成(与transform不同),因此当多个此类动画同时发生时会更慢(并且也可能很昂贵)。

使用边距:

以下代码段通过设置margin-leftmargin-top属性的动画来实现效果。

.animation-1,
.animation-2,
.animation-3 {
  width: 200px;
  height: 200px;
  display: inline-block;
  background: white;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
  vertical-align: middle;
}
.movable-1,
.movable-2,
.movable-3 {
  background: #41A186;
  width: 50px;
  height: 50px;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
}
.movable-1 {
  animation-name: move1;
  animation-duration: 4s;
  animation-delay: 0s;
  animation-fill-mode: forwards;
}
.movable-2 {
  animation-name: move2-right, move2-down;
  animation-duration: 2s, 2s;
  animation-delay: 4s, 6s;
  animation-fill-mode: forwards, forwards;
  animation-timing-function: linear;
}
.movable-3 {
  animation-name: move3-diagonal;
  animation-duration: 4s;
  animation-delay: 8s;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes move1 {
  0% {
    transform: translateX(0px);
  }
  50% {
    transform: translateX(30px);
  }
  100% {
    transform: translateX(30px) translateY(50px);
  }
}
@keyframes move2-right {
  0% {
    margin-left: 0px;
  }
  100% {
    margin-left: 30px;
  }
}
@keyframes move2-down {
  0% {
    margin-top: 0px;
  }
  100% {
    margin-top: 50px;
  }
}
@keyframes move3-diagonal
 {
  0% {
    margin-top: 0px;
    margin-left: 0px;
  }
  100% {
    margin-top: 50px;
    margin-left: 30px;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="animation-1">
  <div class="movable-1">1</div>
</div>
<div class="animation-2">
  <div class="movable-2">2</div>
</div>
<div class="animation-3">
  <div class="movable-3">3</div>
</div>

使用职位:

此代码段通过动画lefttop属性实现了相同的效果。子元素具有position: absolute

.animation-1,
.animation-2,
.animation-3 {
  width: 200px;
  height: 200px;
  display: inline-block;
  background: white;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
  position: relative;
}
.movable-1,
.movable-2,
.movable-3 {
  background: #41A186;
  width: 50px;
  height: 50px;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
  position: absolute;
}
.movable-1 {
  animation-name: move1;
  animation-duration: 4s;
  animation-delay: 0s;
  animation-fill-mode: forwards;
}
.movable-2 {
  animation-name: move2-right, move2-down;
  animation-duration: 2s, 2s;
  animation-delay: 4s, 6s;
  animation-fill-mode: forwards, forwards;
  animation-timing-function: linear;
}
.movable-3 {
  animation-name: move3-diagonal;
  animation-duration: 4s;
  animation-delay: 8s;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}
@keyframes move1 {
  0% {
    transform: translateX(0px);
  }
  50% {
    transform: translateX(30px);
  }
  100% {
    transform: translateX(30px) translateY(50px);
  }
}
@keyframes move2-right {
  0% {
    left: 0px;
  }
  100% {
    left: 30px;
  }
}
@keyframes move2-down {
  0% {
    top: 0px;
  }
  100% {
    top: 50px;
  }
}
@keyframes move3-diagonal {
  0% {
    top: 0px;
    left: 0px;
  }
  100% {
    top: 50px;
    left: 30px;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="animation-1">
  <div class="movable-1">1</div>
</div>
<div class="animation-2">
  <div class="movable-2">2</div>
</div>
<div class="animation-3">
  <div class="movable-3">3</div>
</div>

注意:如我的回答here所述,您当然可以添加包装元素并为其设置下移动画。这会产生与第一个相同的效果,但我不建议采用这种方法,因为它违背了你的问题(在我看来是 - 如何将多个动画添加到同一个元素并使第二个从第一个结束的地方开始)。

.animation-1,
.animation-2 {
  width: 200px;
  height: 200px;
  display: inline-block;
  background: white;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
}
.movable-1,
.movable-2 {
  background: #41A186;
  width: 50px;
  height: 50px;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
}
.movable-1 {
  animation-name: move1;
  animation-duration: 4s;
  animation-delay: 0s;
  animation-fill-mode: forwards;
}
.movable-2 {
  animation-name: move2-right;
  animation-duration: 2s;
  animation-delay: 4s;
  animation-fill-mode: forwards;
}
.movable-2-wrapper {
  animation-name: move2-down;
  animation-duration: 2s;
  animation-delay: 6s;
  animation-fill-mode: forwards;
}
@keyframes move1 {
  0% {
    transform: translateX(0px);
  }
  50% {
    transform: translateX(30px);
  }
  100% {
    transform: translateX(30px) translateY(50px);
  }
}
@keyframes move2-right {
  0% {
    transform: translateX(0px);
  }
  50% {
    transform: translateX(30px);
  }
  100% {
    transform: translateX(30px);
  }
}
@keyframes move2-down {
  0% {
    transform: translateY(0px);
  }
  50% {
    transform: translateY(50px);
  }
  100% {
    transform: translateY(50px);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="animation-1">
  <div class="movable-1">1</div>
</div>
<div class="animation-2">
  <div class='movable-2-wrapper'>
    <div class="movable-2">2</div>
  </div>
</div>