扩展已翻译元素的第一个动画的最终状态 [英] Extend the final state of the first animation for translated element

查看:114
本文介绍了扩展已翻译元素的第一个动画的最终状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



问题:我想知道这个问题,



第二个框有多个动画,试图创建与第一个动画相同的效果。看起来transform属性正在覆盖(因为它应该)* 。我试图扩展第1动画(第2框)与第二动画的属性。尝试使用 animation-fill-mode:forward ,但没有成功。也许我缺少一些基本的东西。可以使用香草CSS吗?



* 参考


'animation-name'适用的动画列表。
如果多个动画是
尝试修改相同的属性,那么最接近
的动画在名称列表的末尾获胜。







要求:



分隔 move2-right move2-down 关键帧规则,但在同一个元素上工作,保留第1个动画变换。






当前输出:



  .animation-1,.animation-2 {width:200px; height:200px; display:inline-block;背景:白色; 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:forward; animation-fill-mode:forward;}。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:forward,forward; animation-fill-mode:forward,forward;} @  -  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>  


$ b

这里是一个可以玩的小提琴: JSfiddle strong>

解决方案

据我所知,这是不可能的纯CSS,因为指示),当我们向已经具有变换的元素添加额外的变换规则时,整个变换被重置,因为它覆盖并且不附加到现有的变换。






  • 处理 animationend 事件。

  • 在处理程序中,获取 translateX )以像素为单位。

  • 获取下一个动画的CSS关键帧规则,修改它们使 translateX / code>作为变换堆栈的第一部分。



你有一个案例,你绝对没有办法使用问题中提到的第一种方法。






方法来实现类似的效果,将动画元素的 margin 位置 c>而不是使用 transform:translate()。这种方法的一个主要缺点是,这不会在GPU层完成(不像 transform ),因此当多个这样的动画同时发生时会更慢



使用边距:

通过动画 margin-left margin-top 属性生效。



  .animation-1,.animation-2,.animation-3 {width:200px; height:200px; display:inline-block;背景:白色; 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:forward;}。movable-2 {animation-name:move2-right,move2-down; animation-duration:2s,2s; animation-delay:4s,6s; animation-fill-mode:向前,向前; animation-timing-function:linear;}。movable-3 {animation-name:move3-diagonal; animation-duration:4s; animation-delay:8s; animation-fill-mode:forward; 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>  


$ b




使用位置



动画效果顶部属性。子元素具有 position:absolute



  .animation- 1,.animation-2,.animation-3 {width:200px; height:200px; display:inline-block;背景:白色; 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,.moveable-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:forward;}。movable-2 {animation-name:move2-right,move2-down; animation-duration:2s,2s; animation-delay:4s,6s; animation-fill-mode:向前,向前; animation-timing-function:linear;}。movable-3 {animation-name:move3-diagonal; animation-duration:4s; animation-delay:8s; animation-fill-mode:forward; animation-timing-function:linear;} @ keyframes move1 {0%{transform:translateX(0px); } 50%{transform:translateX(30px); } 100%{transform:translateX(30像)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>  


$ b




注意:如我的回答中所述在这里,你当然可以添加一个包装器元素并设置向下移动动画。这将产生与第一个相同的效果,但我不是建议这种方法,因为它是对你的问题的点(在我看来 - 如何添加多个动画到同一个元素,使第二个

)。



  .animation-1,.animation-2 {width: 200px; height:200px; display:inline-block;背景:白色; 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:forward;}。movable-2 {animation-name:move2-right; animation-duration:2s; animation-delay:4s; animation-fill-mode:forward;}。movable-2-wrapper {animation-name:move2-down; animation-duration:2s; animation-delay:6s; animation-fill-mode:forward;} @ 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>  


I know this is asked multiple times here, but I am asking for a different approach for these kind of animations.

Problem:

The 2nd box has multiple animations, trying to create the same effect as 1st one. It seems like the transform property is getting overwritten (as it should)*. I am trying to extend the 1st animation (of 2nd box) with the properties of 2nd animation. Tried to use animation-fill-mode: forwards but with no success. Maybe I am missing something basic. Is it possible with vanilla CSS?

*Reference

The ‘animation-name’ property defines a list of animations that apply. If multiple animations are attempting to modify the same property, then the animation closest to the end of the list of names wins.


Requirement:

Separate move2-right and move2-down key-frames rules but work on the same element, preserving the 1st animation transformation. If there is an alternate approach to this kind of animation, please guide me through it.


Current output:

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

Here is a fiddle you can play with: JSfiddle

解决方案

As far as I am aware this is not possible with pure CSS because (as you have already indicated), when we add an extra transformation rule to an element which already has a transform, the whole transform gets reset because it overwrites and does not append to the existing transform.

With JS this might be possible to achieve but even there it is going to be tough because we have to do the following:

  • Handle the animationend event on completion of the first animation.
  • In the handler, get the translateX(...) in pixels.
  • Get the CSS keyframe rules of the next animation, modify them to take the translateX(...) as the first part of the transform stack.

Note: I assume that you have a case where there is absolutely no way for you to use the first method mentioned in the question.


An alternate method to achieve a similar effect would be to animate the margin or position of an element instead of using transform: translate(). One major downside to this approach is that this would not done at the GPU layer (unlike transform) and hence would be slower when multiple such animations happen at the same time (and could also be expensive).

Using Margins:

The below snippet achieves the effect by animating margin-left and margin-top properties.

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


Using Position:

This snippet achieves the same effect by animation left and top properties. The child element has 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>


Note: As described in my answer here, you can of-course add a wrapper element and set the move-down animation to it. This would produce the same effect as the first one but I am not suggesting that approach because it is against the very point of your question (which in my opinion was - how to add multiple animations to the same element and make the second start from where the first ended).

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

这篇关于扩展已翻译元素的第一个动画的最终状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆