iT邦幫忙

1

[Sass]造輪子-用@mixin做一個簡單的loading動畫

話不多說,先上成果!
loading

思考迴路:

  1. 撰寫keyframes使每個點上下移動(transform),我們命名這個keyframe為waving
    waving-nodelay
  2. 每個點都具備相同的基礎屬性(background-color,border-radius等)
  3. 為了達到每個點上下錯動,我們要設法delay每個點的動畫開始時間

在使用Sass前,我們可使的css可以這樣寫

/*使點上下移動的動畫*/
@keyframes waving {
  25% {
    transform: translateY(10px);
  }
  75% {
    transform: translateY(-10px);
  }
  100% {
    transform: translateY(0);
  }
}

.loading .dot {
  /*每個點共通的屬性*/
  display: inline-block;
  margin: 0 10px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background-color: #111;
}
.loading .dot:nth-child(1) {
  /*每個點各自的animation,最後加上他要延遲執行的秒數*/
  animation: waving 2s infinite linear 0s;
}
.loading .dot:nth-child(2) {
  /*每個點各自的animation,最後加上他要延遲執行的秒數*/
  animation: waving 2s infinite linear -1.5s;
}
.loading .dot:nth-child(3) {
  /*每個點各自的animation,最後加上他要延遲執行的秒數*/
  animation: waving 2s infinite linear -3s;
}

觀察這一份css,我們可以總結出
每個點都使用了animation屬性,只是延遲秒數不同,我們可以嘗試將animation屬性分離成Sass的@mixin,並透過傳入參數的方式動態給予延遲秒數,這樣一來便可降低大量重複的程式碼。

@mixin wavingDelay ($delay) {
    animation: waving 2s infinite linear $delay;
}

問題的關鍵點在於如何動態產生延遲秒數,我們可以觀察手上擁有的數值,第1個點延遲0秒,第2個點延遲-1.5秒,第3個點延遲-3秒,也就是我們需要一個公式將1/2/3轉換為0/-1.5/-3,即為-(1.5*(輸入-1))

接下來我們以Sass的@for迴圈產生代表每個點的數字,並在nth-child()@include我們上面的wavingDelay,同時將數字傳遞進入。

.dot{
    /*這裡省略了基礎屬性*/
    @for $i from 1 through 3{
        /*&:nth-child(n) 代表第n個點*/
        &:nth-child(#{$i}){
            /*運算該點的延遲時間並傳遞給@mixin*/
            @include wavingDelay(#{-(1.5*($i - 1))}s);
        }
    }
}

這個範例展示了使用Sass的@for@mixin為元素動畫增加動態延遲秒數,以下是我在CodePen上的實作。

CodePen


尚未有邦友留言

立即登入留言