js+css實現小紅書圖片輪播指示燈效果(選中高亮燈自動居中)


導言

近期實現一個需求,大概就是類似小紅書圖片輪播指示燈那樣,固定只顯示n個指示燈,若n個燈前方或者后方存在更多圖,則n個中最前方或者最后方的燈縮小展示。直接上圖:

【不會上傳視頻。。就湊合看下圖吧

 產品表示:我要一模一樣的,也是五個燈,切換圖片時,指示燈自動滾動,要讓選中的居中,前方或者后方有更多圖,最前或者最后的燈要縮小顯示。

 

實現效果

效果1 

 

效果2 

 

效果3

構思方案

看了小紅書的實際效果后,個人認為實現方案大概是:全部的燈都渲染出來,但是只留出五個燈的顯示寬度,其他的overflow: hidden掉;再根據選中燈的位置,js控制橫向滾動,將選中燈滾動到視區中間;至於縮小的燈,則需要根據每個燈的index去判斷是否縮小顯示。但是具體哪些燈要縮小顯示呢,感覺是一個比較復雜的條件,一旦搞不好可能寫完了自己在看也看不明白了,決定先去網上找找參考方案。

參考方案

https://blog.csdn.net/qq_44656685/article/details/115376854

思路大概是根據總數量和選中燈的index,按照上面的是實現效果一樣,分幾個條件,不同條件渲染不同的燈和小燈,但是存在一個問題:這是一個純靜態的,沒有切換過渡的效果,特別在圖數量較多時,處於效果2的條件就會一直是純靜態的,看起來很奇怪。

綜合考慮后,決定按照構思方案去實現,不過參考方案也給了一定的啟發,那就是哪些燈縮小顯示的條件,這位好人直接給出來了,稍微改改就可以用了。

總結如下:

顯示為小點的條件:總數大於5且 (selectedIndex<3且index>=4 || selectedIndex>=3且selectedIndex<總數-3且index與selectedIndex絕對值差>=2 || selectedIndex>總數-3且index<=總數-5)

果然比較復雜。。。哈哈哈哈

實現方案

CODEPEN

⬆️先放一個鏈接在這里

核心邏輯:

使選中的點滾動至視區中間

搭配css,dotWrapper這個樣式,就是為了控制視區寬度(為5個點+4個間隔的距離),在通過js強制控制scrollLeft使選中點定位到視區中間,window.requestAnimationFrame創造滾動的動畫效果

handleScrollDotView() {
    setTimeout(() => {
      const selected = document.querySelector('.selectedDot');
      const selectedLeft = selected.getBoundingClientRect().x;
      // 將選中的點偏移至中間
      const scrollDom = document.querySelector('.dotWrapper');
      const offset = selectedLeft - (window.innerWidth - 8) / 2;

      const duration = 1000;
      const frames = Math.round(duration / 1000 * 16);
      let frame = 0; // 過渡幀數

      const animate = () => {
        scrollDom.scrollLeft += offset / frames;
        if (++frame < frames) {
          window.requestAnimationFrame(animate);
        }
      };
      window.requestAnimationFrame(animate);
    }, 100);
  }

點縮放的條件:【懶得搞格式了

<div className="dotWrapper">
            {
              new Array(this.state.total).fill({}).map((_, index) => {
                return <div className={
                  `dot
                  ${index === this.state.selectedIndex && 'selectedDot'}
                  ${this.state.total > 5 && (
                    (this.state.selectedIndex < 3 && index >= 4) ||
                    (this.state.selectedIndex >= 3 && this.state.selectedIndex < this.state.total - 3 && Math.abs(index - this.state.selectedIndex) >= 2) ||
                    (this.state.selectedIndex >= this.state.total - 3 && index <= this.state.total - 5)
                  ) && 'smallDot'}`} key={index} />;
              })
            }
          </div>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM