[30DaysChallenge] 製作無限Slider

30DaysChallenge 是自主性每兩天寫一篇技術相關的部落格

DEMO

無限 SLIDER

在程式的世界中,沒有真的無限,也沒有真的隨機

一切都是人類的操控,畢竟程式也是人寫的 XD

無限的方法很多,當然也有方便的套件

以下攻略無限 SLIDER 的邏輯


思考邏輯

這邊用英文字母表現 畫圖好累

實作方式以資料固定,不接觸 DOM、不動到資料為主

  1. 假設你有一組 SLIDER 資料,分別有 ABCDE 各五張圖片

    ABCDE
    
  2. 畫面每次顯示三個,三個一組 (箭頭表示目前顯示的)

    ABC DE
    ^^^
    
  3. 延伸資料,摸擬一下實際的樣子

    可以觀察出當你的資料延伸到一定程度時,會與起點一樣

    這時候如果在神不知鬼不覺的情況下,偷偷回到起點

    使用者就會在神不知鬼不覺的情況下被提升了使用者的體驗 因為可以一直按很爽

    >箭頭處為起點
    ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    >往左走
        ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    >往左走
            ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    >往左走
                ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    >往左走
                    ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    >往左走
                        ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    >偷偷回到起點
    ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
                        ^^^
    
  4. 固定資料、定位

    因為資料固定,以不動到資料為主,需要固定資料的數量

    >以ABCDE來說,五筆資料、一次顯示三筆、需要五次就會回到一模一樣的資料
    
    >設定邊界,起點
    
    ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
    END                 ^^^                 END
    
  5. 當進入畫面時,一開始以中間為預設顯示,可利用 CSS translateX 來達成

    實際需求依照畫面寬度,slider 每筆內容的寬度去計算

    我這邊剛好是以 100%來移動

    counter 往左為負、往右為正 (或顛倒也可)

    translateX 則是+100 則往左邊移動(ABC > CDE),另一邊-100 (ABC > DEA)

    • 往左走 counter - 1x +100%
    • 每當counter 5 || -5 時,將定位回歸起點 x to -500%
    -5  -4  -3  -2  -1   0   1   2   3   4   5    << counter/pointer
    
    000 100 200 300 400 500 600 700 800 900 1000  << X (負號 -%)
    
    ABC DEA BCD EAB CDE ABC DEA BCD EAB CDE ABC
    END                 ^^^                 END   << bound
    
  6. 動畫考量

    如果想要有美麗的滑動,可以設定 transition

    但要注意 當你到邊界,transition要改回0秒,來達到神不知鬼不覺的移動

    必要的話可以將方法非同步的處理,我使用 setTimeout(需搭配你的動畫秒數)

    • 當使用者按下按鈕後,SLIDER 移動
    • 移動完後到達邊界
    • transition 設定為 0 秒
    • translateX 定位到起點處(counter 歸零)
    • transition 設定回 0.2 秒(或你設定的秒數)

CODE HERE (REACT)

動畫相關

//登記位置、動畫秒數、pointer/counter
const [x, setX] = useState(middle)
const [time, setTime] = useState(0.5)
const [pointer, setPointer] = useState(0)

if (pointer === bound) {
  //當到達邊界
  setTime(0) //動畫歸0
  setTimeout(() => {
    setX(middle) //回起點
    setPointer(0) //pointer/counter歸0
  }, 500)
  setTimeout(() => {
    //慢一點執行,還原動畫秒數
    setTime(0.5)
  }, 600)
}

其他詳細的程式碼 promo 相關

下一篇又不知道要寫什麼 08/13