を使用して提出ボタンを作る


週シリーズのウィジェットの第2分割払いへようこそ.
今回は、ローダに変換して提出を確認する送信ボタンを作成する手順を示します.
このウィジェットのためのインスピレーションはthis 以下のようになります.

準備


今日のウィジェットについてはvue.js and tweenlite アニメーション用.両方のライブラリには、任意のプロジェクトにインポートするCDNリンクがあります.

HTML構造


このウィジェットのマークアップは本当に簡単です.私たちはVueのインスタンスがマウントされ、その中にコンテナが必要です.
<div id="submit-button" class="submit-container">
  <div class="submit-btn">
    <span>Submit</span>    
  </div>

  <!--  grey circle  -->
  <svg class="loader-svg">
    <path stroke="#CCCCCC" fill="none" stroke-width="4" d="M25,2.5A22.5,22.5 0 1 1 2.5,25A22.5,22.5 0 0 1 25,2.5"></path>
  </svg>

  <!--  green circle  -->
  <svg class="loader-svg">
    <path stroke="#20BF7E" fill="none" stroke-width="4" d="M25,2.5A22.5,22.5 0 1 1 2.5,25A22.5,22.5 0 0 1 25,2.5"></path>
  </svg>
</div>
では、これらのCSS規則を使って、ボタンのスタイルをマッチングしましょう.
.submit-container {
  position: relative;
  margin: 80px;
}

.submit-btn {
  width: 100px;
  color: #20BF7E;
  font-size: 20px;
  font-family: Arial;
  text-align: center;
  text-decoration: none;
  padding: 10px 20px 10px 20px;
  border: solid #20BF7E 4px;
  text-decoration: none;
  cursor: pointer;
  border-radius: 25px;
  transition: background-color .3s, color .3s;
}

.submit-btn:hover {
  background-color: #20BF7E;
  color: white;
}
我々は今、緑色の背景と白いフォントの間に色をスワップホバーアニメーションを持っているボタンを持っている.また、25 px境界半径のプロパティに注意してください、それは本当に私たちが輪になるために私達のボタンを必要とするときに重要になるだろう.

インタラクション論理


Vueインスタンスを初期化する前に、ボタンの状態をチェックしたいのですが.CSSによって既に解決されているので、ホバーを無視することができます.これらを扱うには、次のようにします.
new Vue({
  el: '#submit-button',
  data: {
    clicked: false,    
    loading: false,
    loaded: false
  }
})
“なぜ3つのBooleansとは、3つの値を持つ単一の文字列または数字ではないか?”そして、理由は彼らが相互に排他的でないので、ボタンが同時にクリックされることができて、同時に「荷を積む」ことができます.

クリックの相互作用


クリックするアニメーションの準備では、まずボタンをクリックしたときにCSSルールを作成する必要があります.それは円に変換され、50 px円で正確に50 px(25 px境界半径を覚えていますか?).問題は、すでにパディングが宣言されており、ボタンの境界を補償する必要があるためです.
.submit-btn {
  ... other rules
  /* more CSS transitions for the props we need to animate */
  transition: width .3s, margin .3s, background-color .3s, color .3s;
}
.submit-btn.round {
  margin-left: 50px;
  border-color: #CCCCCC;
  background: white;

  /*  circle should be 50px width & height */
  /* borderLeft + paddingLeft + paddingRight + borderRight  */
  /* 4 + 20 + 20 + 4 = 48 + 2 = 50 */
  width: 2px; 
  /* borderTop + paddingTop + paddingBottom + borderBottom  */
  /* 4 + 10 + 10 + 4 = 28 + 22 = 50 */
  height: 22px;
}
ここでVUEにボタンをバインドすることができます.最初に、クリックしてメソッドをクリックし、計算されたプロパティに丸クラスをバインドします.また、ボタンをクリックすると送信テキストが消えてしまう必要があります.
...
<div 
  @click="clickedSubmit" 
  :class="buttonClass"
  class="submit-btn">
    <span v-show="!clicked">Submit</span>  
...
それから、我々のJSで:
...
methods: {
  clickedSubmit () {
    this.clicked = true
  }
},
computed: {
  buttonClass () {
    if (this.clicked) {
      return 'round'
    }
    return ''
  }
}
かなり簡単な右?今トリッキーな部分が来る.

読み込み


我々のボタンが円に変わる直後に、我々は我々のSVG円の上に置く必要があります、なぜ?HTMLの境界線は我々がそれらを必要とする方法をアニメーション化することはできませんが、SVGはできます!
さて、このCSSで丸の位置に合わせましょう.
.loader-svg {
  pointer-events: none;
  position: absolute;
  top: 0px;
  left: 50px;
  width: 50px; 
  height: 50px; 
  transform-origin: 25px 25px 25px;
}
そして、両方のSVG円は、ボタンがロードを開始するとき、それらを表示するために、このVue結合を持っています

  <!--  grey circle  -->
  <svg v-if="loading" class="loader-svg">
    ...
  </svg>

  <!--  green circle  -->
  <svg v-if="loading" class="loader-svg">
    ...
  </svg>
私たちは、ボタンアニメーションがいつ終わるか知っている必要がありますMDN web docs ' TransitionEnd 'イベントを使用できます.
VEEでそのイベントにリスナーを追加するには、[送信]ボタンへの参照を必要とします.この行をボタンに追加します.
<div class="submit-btn" 
  ref="submit-btn"
  ...
>
今我々はそれを参照することができますclickedSubmit 以下の方法
...
clickedSubmit () {
  this.clicked = true    
  this.$refs['submit-btn']
    .addEventListener("transitionend", this.animateLoader, false);
}
...
これはanimateLoader アニメーションが終了したらメソッドを作成します.
animateLoader () {
  this.loading = true
  this.$refs['submit-btn']
    .removeEventListener("transitionend", this.animateLoader, false);
  // TODO animate circles
}
それはloading フラグをtrueに設定し、以前に追加したリスナーを削除します.

緑の円のアニメーション


次の部分についてはSVG animation trick 使用stroke-dasharray and stroke-dashoffset プロパティ.
仕事のトリックのためにstroke-dasharray 私たちの幾何学クラスノートブックに戻ることができますし、数式は円周率の円周率を参照してくださいに計算するために円の円周値として持っている必要があります.
我々のものは50 px幅です、それで、それはそうです3.1416 * 50 = ~157 . また、我々はバインドされますstroke-dashoffset 新しいvueデータ変数に
...
<!--  green circle  -->
<svg v-if="loading" class="loader-svg">
  <path stroke="#20BF7E" fill="none" stroke-width="4" d="M25,2.5A22.5,22.5 0 1 1 2.5,25A22.5,22.5 0 0 1 25,2.5" 
  stroke-dasharray="157" :stroke-dashoffset="loaderOffset">
  </path>
</svg>
...
Vueインスタンスでは、データオブジェクト、LoaderOffsetプロパティ内で宣言し、同じ値で初期化します157 :
data: {
  clicked: false,    
  loading: false,
  loaded: false,
  loaderOffset: 157
}
その後、TweenLiteでローダをアニメーション化できます.
我々はTweenLite.to() 補間するメソッドloaderOffset プロパティを初期値から2秒でゼロにする.
アニメーション化するとonComplete フックはcompleteLoading 設定する方法loading and loaded プロパティー
...
animateLoader () {
  this.loading = true
  this.$refs['submit-btn']
    .removeEventListener("transitionend", this.animateLoader, false);

  // animate the loaderOffset property,
  // on production this should be replaced 
  // with the real loading progress
  TweenLite.to(this, 2, {
    loaderOffset: 0, // animate from 157 to 0
    ease: Power4.easeInOut,
    onComplete: this.completeLoading // execute this method when animation ends
  })
},
completeLoading () {
  this.loading = false
  this.loaded = true
}
...

積載状態


最後の部分では、私たちのボタンがロードされたときに使用される別のCSS規則を作成する必要があります.
.submit-btn.loaded {
  color: white;
  background-color: #20BF7E;
}
それからbuttonClass Computerプロパティはこの場合も処理します.
...
buttonClass () {
  if (this.loaded) {
    return 'loaded'
  }

  if (this.clicked) {
    return 'round'
  }

  return ''
}
...
これらのプロパティのCSS遷移をすでに宣言したので、何もする必要はありません.
そして今、最終的な結果!
それは週の2番目のウィジェットのためです.
あなたが前のものをチェックしなかったならば、...
また、あなたは来週の特定のウィジェットを参照したい場合は、コメントのセクションでそれを投稿してください.