【问题标题】:Trying to recreate a shake animation like Stripe尝试重新创建像 Stripe 这样的抖动动画
【发布时间】:2015-12-18 15:06:01
【问题描述】:

当出现一些表单填写错误时,我正在尝试重新创建负摇动动画,就像 Strike 在他们的支付框中使用的那样。

我基本上复制了它的动画关键帧,但在我的使用中它的工作方式不同。

我的版本:

http://codepen.io/FelipeMartinin/pen/NGrXvR

条纹版本:

https://stripe.com/docs/checkout(点击“刷卡支付”按钮,点击“支付”后不填输入即可查看动画)

如果你注意到,Stripe 动画有 3d 运动效果,而在我的版本中,盒子只是水平抖动。即使使用相同的关键帧。

跟随关键帧下方

@keyframes panelShakeAnimation {
  0 {
    -webkit-transform: translateX(0);
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -o-transform: translateX(0);
    transform: translateX(0)
  }

  12.5% {
    -webkit-transform: translateX(-6px) rotateY(-5deg);
    -moz-transform: translateX(-6px) rotateY(-5deg);
    -ms-transform: translateX(-6px) rotateY(-5deg);
    -o-transform: translateX(-6px) rotateY(-5deg);
    transform: translateX(-6px) rotateY(-5deg)
  }

  37.5% {
    -webkit-transform: translateX(5px) rotateY(4deg);
    -moz-transform: translateX(5px) rotateY(4deg);
    -ms-transform: translateX(5px) rotateY(4deg);
    -o-transform: translateX(5px) rotateY(4deg);
    transform: translateX(5px) rotateY(4deg)
  }

  62.5% {
    -webkit-transform: translateX(-3px) rotateY(-2deg);
    -moz-transform: translateX(-3px) rotateY(-2deg);
    -ms-transform: translateX(-3px) rotateY(-2deg);
    -o-transform: translateX(-3px) rotateY(-2deg);
    transform: translateX(-3px) rotateY(-2deg)
  }

  87.5% {
    -webkit-transform: translateX(2px) rotateY(1deg);
    -moz-transform: translateX(2px) rotateY(1deg);
    -ms-transform: translateX(2px) rotateY(1deg);
    -o-transform: translateX(2px) rotateY(1deg);
    transform: translateX(2px) rotateY(1deg)
  }

  100% {
    -webkit-transform: translateX(0);
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -o-transform: translateX(0);
    transform: translateX(0)
  }
}

.headShake {
  -webkit-animation-duration: 400ms;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-name: panelShakeAnimation;
  -moz-animation-duration: 400ms;
  -moz-animation-timing-function: ease-in-out;
  -moz-animation-name: panelShakeAnimation
}

如何让我的动画像 Stripe 一样工作?谢谢!

【问题讨论】:

    标签: css animation keyframe


    【解决方案1】:

    您只需在容器元素上添加perspective 规则。这使得转换将出现在 3D 空间中。

    现场演示:

    $("button").on('click', function(e) {
    	e.preventDefault();
      
    	$(".card").toggleClass("headShake");
    });
    /* Basic Reset */
    *,
    *:after,
    *:before {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    html {
      font-size: 62.5%;
    }
    
    body {
      font-size: 1.8em;
      line-height: 1.875;
      font-family: "Roboto", sans-serif;
      font-weight: 400;
      color: #555;
      background-color: #eeeeee;
    }
    
    /* Basics Styles */
    a {
      text-decoration: none;
      color: #2196f3;
    }
    
    h1, h2, h3 {
      margin-bottom: 1.2rem;
      line-height: 1.5;
    }
    
    h1 {
      font-size: 4.8rem;
    }
    
    h2 {
      font-size: 3.2rem;
    }
    
    h4 {
      font-size: 1.8rem;
      font-weight: 300;
    }
    
    .lead {
      font-size: 1.8rem;
    }
    
    p {
      margin-bottom: 1.5rem;
    }
    
    .main-title {
      font-weight: 100;
      font-size: 32px;
      text-align: center;
    }
    
    .main-subtitle {
      font-weight: 100;
      font-size: 18px;
      text-align: center;
    }
    
    .text-small {
      font-size: 75%;
    }
    
    .text-right {
      text-align: right;
    }
    
    .text-left {
      text-align: left;
    }
    
    .text-center {
      text-align: center;
    }
    
    .left {
      float: left;
    }
    
    .right {
      float: right;
    }
    
    .display__inline {
      display: inline;
    }
    
    /* Padding Helpers */
    .padding-tb {
      padding-top: 3%;
      padding-bottom: 3%;
    }
    
    /* Basic Demo Styles */
    .site-container {
      max-width: 320px;
      margin: 10px auto;
      padding-left: 0.6em;
      padding-right: 0.6em;
    }
    @media screen and (min-width: 60.063em) {
      .site-container {
        max-width: 400px;
      }
    }
    
    .footer__content {
      margin-top: 1.6rem;
    }
    
    /* Card */
    .card {
      top: 250px;
      position: relative;
      overflow: hidden;
      background-color: white;
      box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.24), 0 1px 2px 0 rgba(0, 0, 0, 0.12);
      border-radius: 2px;
      padding: 1em;
    }
    .card h3 {
      font-weight: bold;
    }
    
    /* Material Design Form Inputs */
    .form__wrapper {
      overflow: hidden;
      position: relative;
      z-index: 1;
      display: inline-block;
      margin-bottom: 1.6rem;
      width: 100%;
      vertical-align: top;
    }
    
    .form__wrapper--submit {
      padding: 1.6rem 0;
    }
    
    .form__input {
      display: block;
      position: relative;
      margin-top: 1em;
      padding: 0.84em 0;
      width: 100%;
      box-sizing: border-box;
      color: #444;
      font-size: 1.6rem;
      outline: 0;
      border: none;
      border-bottom: solid 1px #ddd;
      -webkit-transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -moz-transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -o-transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 96%, #2196f3 4%);
      background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 96%, #2196f3 4%);
      background-position: -400px 0;
      background-size: 400px 100%;
      background-repeat: no-repeat;
      /**
       * Remove default box-shadow for required pseudo classes 
       */
      /**
       *  When input contain a class of .error 
       */
    }
    .form__input:required {
      box-shadow: none;
    }
    .form__input.error {
      -webkit-transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -moz-transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -o-transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      transition: all 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 96%, #f44336 4%);
      background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 96%, #f44336 4%);
      background-position: 0 0;
      background-size: 400px 100%;
      background-repeat: no-repeat;
    }
    .form__input:focus {
      background-position: 0 0;
      color: #444;
      -webkit-transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -moz-transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -o-transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
    }
    
    /* Form Label */
    .form__label {
      position: absolute;
      bottom: 0;
      left: 0;
      padding: 0;
      width: 100%;
      height: calc(100% - 1em);
      text-align: left;
      pointer-events: none;
      color: #999;
    }
    
    /* Form Label Content */
    .form__label-content {
      position: absolute;
      -webkit-transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -moz-transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      -o-transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
      transition: transform 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
    }
    
    /**
     * 1. When input is focused move the label to top
     * 2. when the input field has a value move the label to top
     */
    .form__input:focus ~ .form__label .form__label-content,
    .form--filled .form__label-content {
      font-size: 1.4rem;
      -webkit-transform: translate3d(0, -65%, 0);
      -moz-transform: translate3d(0, -65%, 0);
      transform: translate3d(0, -65%, 0);
    }
    
    /**
     * Error Styles
     * .error class generated by jquery.validate.min.js plugin
     */
    .error {
      font-size: 1.4rem;
      color: #f44336;
      display: block;
    }
    
    /* Basic Buttons */
    .btn {
      display: inline-block;
      padding: 0.6em 1.5em;
      border-radius: 2px;
      background-color: #2196f3;
      color: #fff;
      border: 0;
      outline: none;
      cursor: pointer;
      font-family: inherit;
      font-weight: 400;
      font-size: 1.6rem;
      box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.24), 0 1px 2px 0 rgba(0, 0, 0, 0.12);
      transition: all 0.2s ease;
    }
    .btn:focus, .btn:hover {
      background-color: #0d8aee;
    }
    .btn.btn-block {
      width: 100%;
      display: block;
    }
    
    /* Modal Styles */
    .modal {
      overflow: hidden;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: #fff;
      padding: 1em;
      z-index: 999;
      border-radius: 2px;
      -webkit-transform: translate3d(0, 100%, 0);
      -moz-transform: translate3d(0, 100%, 0);
      transform: translate3d(0, 100%, 0);
      -webkit-transition: transform 0.3s cubic-bezier(0, 0.795, 0, 1);
      -moz-transition: transform 0.3s cubic-bezier(0, 0.795, 0, 1);
      -ms-transition: transform 0.3s cubic-bezier(0, 0.795, 0, 1);
      -o-transition: transform 0.3s cubic-bezier(0, 0.795, 0, 1);
      transition: transform 0.3s cubic-bezier(0, 0.795, 0, 1);
    }
    
    /* Close icon style for model */
    .modal--close {
      display: block;
      float: right;
      cursor: pointer;
      width: 32px;
      height: 32px;
      line-height: 32px;
      text-align: center;
      font-size: 1.6em;
      color: #888;
    }
    
    .modal--open {
      -webkit-transform: translate3d(0, 0, 0);
      -moz-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
    }
    
    
    @-moz-keyframes panelShakeAnimation {
      0 {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    
      12.5% {
        -webkit-transform: translateX(-6px) rotateY(-5deg);
        -moz-transform: translateX(-6px) rotateY(-5deg);
        -ms-transform: translateX(-6px) rotateY(-5deg);
        -o-transform: translateX(-6px) rotateY(-5deg);
        transform: translateX(-6px) rotateY(-5deg)
      }
    
      37.5% {
        -webkit-transform: translateX(5px) rotateY(4deg);
        -moz-transform: translateX(5px) rotateY(4deg);
        -ms-transform: translateX(5px) rotateY(4deg);
        -o-transform: translateX(5px) rotateY(4deg);
        transform: translateX(5px) rotateY(4deg)
      }
    
      62.5% {
        -webkit-transform: translateX(-3px) rotateY(-2deg);
        -moz-transform: translateX(-3px) rotateY(-2deg);
        -ms-transform: translateX(-3px) rotateY(-2deg);
        -o-transform: translateX(-3px) rotateY(-2deg);
        transform: translateX(-3px) rotateY(-2deg)
      }
    
      87.5% {
        -webkit-transform: translateX(2px) rotateY(1deg);
        -moz-transform: translateX(2px) rotateY(1deg);
        -ms-transform: translateX(2px) rotateY(1deg);
        -o-transform: translateX(2px) rotateY(1deg);
        transform: translateX(2px) rotateY(1deg)
      }
    
      100% {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    }
    
    @-webkit-keyframes panelShakeAnimation {
      0 {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    
      12.5% {
        -webkit-transform: translateX(-6px) rotateY(-5deg);
        -moz-transform: translateX(-6px) rotateY(-5deg);
        -ms-transform: translateX(-6px) rotateY(-5deg);
        -o-transform: translateX(-6px) rotateY(-5deg);
        transform: translateX(-6px) rotateY(-5deg)
      }
    
      37.5% {
        -webkit-transform: translateX(5px) rotateY(4deg);
        -moz-transform: translateX(5px) rotateY(4deg);
        -ms-transform: translateX(5px) rotateY(4deg);
        -o-transform: translateX(5px) rotateY(4deg);
        transform: translateX(5px) rotateY(4deg)
      }
    
      62.5% {
        -webkit-transform: translateX(-3px) rotateY(-2deg);
        -moz-transform: translateX(-3px) rotateY(-2deg);
        -ms-transform: translateX(-3px) rotateY(-2deg);
        -o-transform: translateX(-3px) rotateY(-2deg);
        transform: translateX(-3px) rotateY(-2deg)
      }
    
      87.5% {
        -webkit-transform: translateX(2px) rotateY(1deg);
        -moz-transform: translateX(2px) rotateY(1deg);
        -ms-transform: translateX(2px) rotateY(1deg);
        -o-transform: translateX(2px) rotateY(1deg);
        transform: translateX(2px) rotateY(1deg)
      }
    
      100% {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    }
    
    @-o-keyframes panelShakeAnimation {
      0 {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    
      12.5% {
        -webkit-transform: translateX(-6px) rotateY(-5deg);
        -moz-transform: translateX(-6px) rotateY(-5deg);
        -ms-transform: translateX(-6px) rotateY(-5deg);
        -o-transform: translateX(-6px) rotateY(-5deg);
        transform: translateX(-6px) rotateY(-5deg)
      }
    
      37.5% {
        -webkit-transform: translateX(5px) rotateY(4deg);
        -moz-transform: translateX(5px) rotateY(4deg);
        -ms-transform: translateX(5px) rotateY(4deg);
        -o-transform: translateX(5px) rotateY(4deg);
        transform: translateX(5px) rotateY(4deg)
      }
    
      62.5% {
        -webkit-transform: translateX(-3px) rotateY(-2deg);
        -moz-transform: translateX(-3px) rotateY(-2deg);
        -ms-transform: translateX(-3px) rotateY(-2deg);
        -o-transform: translateX(-3px) rotateY(-2deg);
        transform: translateX(-3px) rotateY(-2deg)
      }
    
      87.5% {
        -webkit-transform: translateX(2px) rotateY(1deg);
        -moz-transform: translateX(2px) rotateY(1deg);
        -ms-transform: translateX(2px) rotateY(1deg);
        -o-transform: translateX(2px) rotateY(1deg);
        transform: translateX(2px) rotateY(1deg)
      }
    
      100% {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    }
    
    @-ms-keyframes panelShakeAnimation {
      0 {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    
      12.5% {
        -webkit-transform: translateX(-6px) rotateY(-5deg);
        -moz-transform: translateX(-6px) rotateY(-5deg);
        -ms-transform: translateX(-6px) rotateY(-5deg);
        -o-transform: translateX(-6px) rotateY(-5deg);
        transform: translateX(-6px) rotateY(-5deg)
      }
    
      37.5% {
        -webkit-transform: translateX(5px) rotateY(4deg);
        -moz-transform: translateX(5px) rotateY(4deg);
        -ms-transform: translateX(5px) rotateY(4deg);
        -o-transform: translateX(5px) rotateY(4deg);
        transform: translateX(5px) rotateY(4deg)
      }
    
      62.5% {
        -webkit-transform: translateX(-3px) rotateY(-2deg);
        -moz-transform: translateX(-3px) rotateY(-2deg);
        -ms-transform: translateX(-3px) rotateY(-2deg);
        -o-transform: translateX(-3px) rotateY(-2deg);
        transform: translateX(-3px) rotateY(-2deg)
      }
    
      87.5% {
        -webkit-transform: translateX(2px) rotateY(1deg);
        -moz-transform: translateX(2px) rotateY(1deg);
        -ms-transform: translateX(2px) rotateY(1deg);
        -o-transform: translateX(2px) rotateY(1deg);
        transform: translateX(2px) rotateY(1deg)
      }
    
      100% {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    }
      
    @keyframes panelShakeAnimation {
      0 {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    
      12.5% {
        -webkit-transform: translateX(-6px) rotateY(-5deg);
        -moz-transform: translateX(-6px) rotateY(-5deg);
        -ms-transform: translateX(-6px) rotateY(-5deg);
        -o-transform: translateX(-6px) rotateY(-5deg);
        transform: translateX(-6px) rotateY(-5deg)
      }
    
      37.5% {
        -webkit-transform: translateX(5px) rotateY(4deg);
        -moz-transform: translateX(5px) rotateY(4deg);
        -ms-transform: translateX(5px) rotateY(4deg);
        -o-transform: translateX(5px) rotateY(4deg);
        transform: translateX(5px) rotateY(4deg)
      }
    
      62.5% {
        -webkit-transform: translateX(-3px) rotateY(-2deg);
        -moz-transform: translateX(-3px) rotateY(-2deg);
        -ms-transform: translateX(-3px) rotateY(-2deg);
        -o-transform: translateX(-3px) rotateY(-2deg);
        transform: translateX(-3px) rotateY(-2deg)
      }
    
      87.5% {
        -webkit-transform: translateX(2px) rotateY(1deg);
        -moz-transform: translateX(2px) rotateY(1deg);
        -ms-transform: translateX(2px) rotateY(1deg);
        -o-transform: translateX(2px) rotateY(1deg);
        transform: translateX(2px) rotateY(1deg)
      }
    
      100% {
        -webkit-transform: translateX(0);
        -moz-transform: translateX(0);
        -ms-transform: translateX(0);
        -o-transform: translateX(0);
        transform: translateX(0)
      }
    }
    
    .headShake {
      -webkit-animation-duration: 400ms;
      -webkit-animation-timing-function: ease-in-out;
      -webkit-animation-name: panelShakeAnimation;
      -moz-animation-duration: 400ms;
      -moz-animation-timing-function: ease-in-out;
      -moz-animation-name: panelShakeAnimation;
    }
    
    .site-container {
      -webkit-perspective: 800px;
      perspective: 800px;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h1 class="main-title">Head Shake Animation</h1>
    <h2 class="main-subtitle">An amazing animation for negative feedbacks</h2>
    
    	<section class="site-container padding-tb">
    		
    		<section class="card" style="opacity: 1; transition: none; transform: translateY(0px) scale(1); margin-top: -244px;">
    			
    			<h3 >Login Form</h3>
    
    			<form action="#" class="form" method="post">
    			    <div class="form__wrapper">
    			        <input type="email" class="form__input" id="email" name="email">
    			        <label class="form__label" for="email">
    						<span class="form__label-content">Email</span>
    					</label>
    			     </div>
    
    			    <div class="form__wrapper">
    			        <input type="password" class="form__input" id="password"  name="password">
    			        <label class="form__label" for="password">
    						<span class="form__label-content">Password</span>
    					</label>
    			       
    			     </div>
    
    			    <div class="form__wrapper--submit">
    			    	<div class="form__input-submit">
    			        	<button  class="btn btn-block">Submit to run</button>
    			        </div>
    			    </div>
    			</form>
    			 
    
    		</section><!-- /card -->
    
    
    			</section><!-- /site-container -->

    【讨论】:

      【解决方案2】:

      为容器添加透视图,以获得 3-d 效果

      .site-container {
        max-width: 320px;
        margin: 10px auto;
        padding-left: 0.6em;
        padding-right: 0.6em;
        perspective: 400px;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        相关资源
        最近更新 更多