<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          中心點靠近動畫解析

          共 3175字,需瀏覽 7分鐘

           ·

          2022-06-19 16:10

          背景

          今天要解析的是一種常見動畫效果,特點是:一排橫行排列的卡片,被激活的卡片盡可能移動到中間位置。我給它命名為【中心點靠近動畫】,先看下動畫效果:

          解析

          要實現(xiàn)動畫效果,個人總結(jié)有下面兩個核心點:

          1. 運動動畫基于什么實現(xiàn)?
          2. 每個卡片的運動到中心點的距離怎么計算?

          1、運動動畫基于什么實現(xiàn)?

          針對第一個問題比較好解決,大致可以分為兩種,一種是基于scrollLeft來控制卡片位置,一種是基于css3動畫屬性transform實現(xiàn)。兩種方式各有優(yōu)劣,具體如下:

          scrollLeft

          優(yōu)點:在實現(xiàn)點擊移動的效果下,能夠利用div的滾動特性,快速實現(xiàn)橫向滑動效果。

          缺點:動畫性能較低。

          transform

          優(yōu)點:基于CSS3實現(xiàn),動畫性能高。

          缺點:橫向滾動效果需要單獨實現(xiàn)。

          這次是選用的transform實現(xiàn)的

          html代碼

          <div class="container">
              <div class="list" 
                  ref="listRef"
                  style={{transform: `translateX(${translateX}px)` }}
              >
                  <div class="cardItem">1</div>
                  <div class="cardItem">2</div>
                  <div class="cardItem">3</div>
                  <div class="cardItem">4</div>
                  <div class="cardItem">5</div>
                  <div class="cardItem">6</div>
                  <div class="cardItem active">7</div>
                  <div class="cardItem">8</div>
              </div>
          </div>

          .container {
              position: relative;
              overflow: hidden;

              .list {
                  display: flex;
                  transition: 0.3s ease-in-out;
              }
          }

          2、每個卡片的運動到中心點的距離怎么計算

          這個問題是今天講的重點內(nèi)容,畫了一個簡潔的示意圖

          每個卡片向中心點靠近時,list偏移的距離都是固定的。所以可以將list以中心點為分界線,分成兩個部分。

          active卡片中心點距離list左邊距的距離為offsetLeft

          1. 如果offsetLeft < w/2,也就是中心點的左側(cè)部分卡片,偏移距離translateX = 0;
          2. 如果offsetLeft > w/2,也就是中心點右側(cè)部分卡片,運動到中心點需要偏移dis=offsetLeft-w/2,但是需要檢查右邊隱藏部分內(nèi)容的寬度scrollRight,偏移距離需要為兩者之間的最小值Math.min(dis, scrollRight)

          注意點:當(dāng)L < w時,也就是列表長度小于容器長度時,偏移距離都是0;

          代碼如下:

          // 其中cardW為卡片寬度
          useEffect(() => {
              const cardDomList = listRef.current?.children;
              if (cardDomList) {
                const leftDis = cardDomList[videoIndex].offsetLeft + cardW / 2;
                const scrollRight = L > w ? L - w : 0;
                if (leftDis < w / 2) {
                  setTranslateX(0);
                } else {
                  const dis = leftDis - w / 2;
                  setTranslateX(-Math.min(dis, scrollRight));
                }
              }
            }, [videoIndex]);

          總結(jié)

          解決方案整體是一個距離計算的算法,相對于之前計算方案,感覺這個計算方式更簡潔,具有通用性。

          瀏覽 75
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久黄色精品视频 | 美女91aaa | 五月婷婷丁香在线导航 | 久久婷婷国产综合精品_国产激情 | 欧美内射视频播放 |