【问题标题】:Multiple CSS Transforms on class change using the CSS animation property使用 CSS 动画属性对类更改进行多个 CSS 变换
【发布时间】:2016-11-08 23:11:25
【问题描述】:

.move 类仅使用 CSS 添加到 .box 时,如何激活 CSS 动画?动画应该首先平移,当平移完成后,旋转应该从平移结束的地方开始。另外,当.move 类被移除时,如何使动画的结束状态保持 100% 并重置为 0%?

$(".test").click(function(){
	$(".box").toggleClass("move")
});
body{
  padding: 45px;
}

.test{
  margin-top: 15px;
}

.box{
  height: 45px;
  width: 45px;
  background: black;
}

.move{
  background: blue;
}

.box{
  animation: slide 0.5s, rotate 0.5s;
  animation-delay: 0s, 0.5s;
}

@keyframes slide{
  100%{
    transform: translateX(450px);
  }
}

@keyframes rotate{
  100%{
    transform: rotate(45deg);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
  
</div>
<button class="test">Toggle</button>

【问题讨论】:

    标签: html css css-transitions css-transforms


    【解决方案1】:

    您可以通过将它们放在一起来添加多个转换:

    transform:translateX(450px) rotate(45deg);

    要对关键帧动画执行此操作,您需要将所有阶段作为单个动画执行。您需要将动画应用到 .move 类并设置 animation-fill-mode: forwards 以保留最后一帧,直到删除该类。

    $(".test").click(function(){
    	$(".box").toggleClass("move")
    });
    body{
      padding: 45px;
    }
    
    .test{
      margin-top: 15px;
    }
    
    .box{
      height: 45px;
      width: 45px;
      background: black;
    }
    
    .move{
      background: blue;
      animation: slide 1s;
      animation-fill-mode: forwards;
    }
    
    
    @keyframes slide{
      50%{
        transform: translateX(450px);
        
      }
      100%{
        transform:translateX(450px) rotate(45deg);
      }
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="box">
      
    </div>
    <button class="test">Toggle</button>

    【讨论】:

    • 虽然您的解决方案很好,但您仍然可以处理演示文稿:为什么要包含所有 CSS 但不包含 HTML 或 JS 以使 sn-p 工作并消除链接到外部网站?
    • 我比其他人更喜欢这个答案(包括我的!),因为它不需要将transform: translateX(450px) 替换为margin-left: 450px 之类的其他内容。
    • @WoodrowBarlow 谢谢!是的,虽然 margin-left 在此示例中产生相同的结果,但根据页面上发生的其他情况,它可能会导致布局问题,因此可能有原因需要使用 translateX
    【解决方案2】:

    这可以通过在元素上设置多个转换并结合transition-delay 属性来实现。

    注意:由于每个转换都与属性一一对应,并且由于您将 transform 属性用于“移动”和“旋转”操作,因此它不会按照您编写的方式工作它。

    对于“移动”操作,我使用的是 margin-left 而不是 transform 属性。您可以使用任何方法,只要它是可动画的并且不会重载您用于其他转换之一的属性。

    $(".test").click(function(){
      $(".box").toggleClass("move")
    });
    body {
      padding: 45px;
    }
    .test {
      margin-top: 15px;
    }
    .box {
      height: 45px;
      width: 45px;
      background: black;
      transition:
        margin-left 0.5s,
        transform 0.5s;
      /* delays for when the .move class was just removed */
      transition-delay: 0.5s, 0s;
    }
    .box.move {
      background: blue;
      margin-left: 450px;
      transform: rotate(45deg);
      /* delays for when the .move class was just added */
      transition-delay: 0s, 0.5s;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="box">
      
    </div>
    <button class="test">Toggle</button>

    你也可以直接在转换简写属性中指定延迟,像这样。

    /* transitions for when the .move class was just removed */
    transition:
      margin-left 0.5s 0.5s,
      transform 0.5s 0s;
    

    【讨论】:

      【解决方案3】:

      您正在寻找的似乎是基于transition 的解决方案,而不是animation(除非我误解了您在寻找什么,在这种情况下请发表评论):

      $(".test").click(function(){
        $(".box").toggleClass("move")
      });
      .test, .box {
        margin-top: 15px;
      }
      .box {
        height: 45px;
        width: 45px;
        background: black;
        position: relative;
        left: 0;
        transition: left 5s, transform 5s linear 5s;
      }
      .box.move {
        background: blue;
        left: 450px;
        transform: rotate(45deg);
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div class="box">
        
      </div>
      <button class="test">Toggle</button>

      【讨论】:

      • 我想要的是首先进行翻译。一旦到达终点,旋转应该开始
      【解决方案4】:

      这可能会使您尝试执行的操作无效,但您设置了两次转换 - 如果您需要在一个元素上定位多个转换属性,则需要在一个转换声明中进行,如下所示:

      .box{
        animation: boxStuff 0.5s
      }
      
      @keyframes boxStuff{
        100%{
          transform: translateX(450px) rotate(45deg);;
        }
      }
      

      否则,无论哪个更靠下,都会覆盖另一个。也许您可以使用边距或其他东西而不是 translateX 来解决这个问题?

      对于您问题的另一半,您应该能够将其添加到 .move 类中以在最后一个动画帧上停止,直到移动类被删除。

      animation-fill-mode: forwards;
      

      【讨论】:

      • 我可以不让盒子先平移再旋转吗?
      【解决方案5】:

      如果我理解正确,这就是你想要的结果。

      <a class="test">Toggle</a>
      <div class="box"></div>
      
      .box {
         width: 200px;
         height: 200px;
         margin-left: 0;
         background: gold;
         transform: rotate(0deg);
         transition:  transform .3s 0s, margin .3s .3s;
      }
      
      .move {
         margin-left: 50px;
         transform: rotate(45deg);
         transition: margin .3s 0s, transform .3s .3s;
      }
      

      这是一个小提琴https://jsfiddle.net/VilleKoo/owsm0f7h/1/

      【讨论】:

        猜你喜欢
        • 2012-06-13
        • 2021-12-07
        • 2013-08-07
        • 1970-01-01
        • 2013-08-30
        • 2013-01-01
        • 2012-07-13
        • 2018-02-22
        • 2023-02-11
        相关资源
        最近更新 更多