欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Vue實(shí)現(xiàn)卡片無(wú)限滾動(dòng)動(dòng)畫

 更新時(shí)間:2022年05月07日 16:47:29   作者:ishy  
這篇文章主要為大家詳細(xì)介紹了如何利用Vue制作出卡片無(wú)限滾動(dòng)動(dòng)畫,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定幫助,需要的可以參考一下

概要設(shè)計(jì)

設(shè)置css的animation在適當(dāng)?shù)臅r(shí)間點(diǎn)重置動(dòng)畫來(lái)現(xiàn)實(shí)視覺(jué)上無(wú)限滾動(dòng)的效果。

詳細(xì)設(shè)計(jì)

計(jì)算動(dòng)畫中所需預(yù)設(shè)的卡片dom節(jié)點(diǎn)個(gè)數(shù)(即視覺(jué)上最多能看到的卡片個(gè)數(shù)),如圖1視窗高度為120px,卡片高度為56px,上下margin均為24px,因此一張卡片最多占據(jù)56+24*2=104px。當(dāng)卡片處于視窗垂直居中的位置時(shí),卡片上下各有(120-104)/2 = 8px的高度來(lái)承載其余卡片,因此所需預(yù)設(shè)卡片dom節(jié)點(diǎn)個(gè)數(shù)為3個(gè)。

圖1

圖2

設(shè)置動(dòng)畫的運(yùn)動(dòng)軌跡和持續(xù)時(shí)間來(lái)達(dá)到視覺(jué)上循環(huán)滾動(dòng)的效果。如圖3初始狀態(tài)下第一張卡片位置處于距離視窗頂部24px的位置,當(dāng)?shù)诙埧ㄆ\(yùn)動(dòng)到距離視窗頂部24px的位置時(shí)重置動(dòng)畫即可達(dá)到視覺(jué)上連續(xù)滾動(dòng)的效果。計(jì)算卡片需要向上滾動(dòng)的公式為【初始距頂部距離 - 目標(biāo)距頂部距離】即56+24*2-24=80px,因此設(shè)置動(dòng)畫幀的目標(biāo)位置為transform: translateY(-80px)。

代碼實(shí)現(xiàn):

<template>
  <div class="wrapper">
    <div class="container">
      <div class="content" v-for="i in 3" :key="i">
        <img
          class="image"
          src="https://static-legacy.dingtalk.com/media/lADPDhmOwd9ZBQXNA8DNA8A_960_960.jpg"
          alt=""
        />
        <span>點(diǎn)五已獲得500元京東卡</span>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
 
export default defineComponent({
  setup() {},
});
</script>
<style scoped>
.wrapper {
  height: 500px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.container {
  width: 300px;
  height: 120px;
  overflow: hidden;
  background: #ccc;
}
.content {
  width: 290px;
  height: 56px;
  display: flex;
  margin: 24px auto;
  background: #fff;
  border-radius: 100px;
  flex-flow: row nowrap;
  align-items: center;
  backdrop-filter: blur(4px);
  animation: scroll 3s linear 1s infinite;
}
.image {
  width: 36px;
  height: 36px;
  margin: auto 10px;
  border-radius: 100%;
}
span {
  font-family: PingFang SC;
  font-size: 20px;
  line-height: 20px;
  text-align: center;
}
@keyframes scroll {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-80px);
  }
}
</style>

效果展示:

進(jìn)階功能

動(dòng)態(tài)更新卡片的數(shù)據(jù)

功能分析

卡片仍保持無(wú)限滾動(dòng),但每張卡片展示的數(shù)據(jù)均不同,也就是說(shuō)滾動(dòng)時(shí)視窗內(nèi)的dom節(jié)點(diǎn)不是每次都相同的。

概要設(shè)計(jì)

基于上述功能分析由此可以衍生出兩個(gè)設(shè)計(jì)思路:

  • 展示多少條數(shù)據(jù)就渲染多少個(gè)dom節(jié)點(diǎn),簡(jiǎn)單粗暴無(wú)需考慮動(dòng)態(tài)更新數(shù)據(jù)問(wèn)題;當(dāng)數(shù)據(jù)量大時(shí)會(huì)導(dǎo)致頁(yè)面性能變差,除非數(shù)據(jù)量較少否則不推薦。
  • 固定dom節(jié)點(diǎn)數(shù),在dom節(jié)點(diǎn)移動(dòng)到視窗之外即進(jìn)行數(shù)據(jù)更新;需保證修改dom節(jié)點(diǎn)時(shí)不會(huì)導(dǎo)致視窗內(nèi)的卡片閃爍;(采納)

詳細(xì)設(shè)計(jì)

1.根據(jù)當(dāng)前視窗寬高以及卡片寬高,設(shè)置六個(gè)卡片dom節(jié)點(diǎn),并將每三張卡片分一個(gè)塊,這里分兩個(gè)塊為card1、card2(如下圖)。

2.將兩個(gè)塊的位置重疊(為了方便設(shè)計(jì)動(dòng)畫),card2向上移動(dòng)(56+24)*3=240px的距離。

3.計(jì)算card2動(dòng)畫需要延遲執(zhí)行的時(shí)間。這里我設(shè)置每個(gè)card塊動(dòng)畫移動(dòng)距離為480px,執(zhí)行時(shí)間為12s,那么card2延遲執(zhí)行的時(shí)間公示為【延遲距離(card高度)/速度】即240/480/12 = 6s。所以動(dòng)畫幀設(shè)置為

@keyframes scroll1 {
  from {
    transform: translateY(0);
    left: 0;
  }
  to {
    transform: translateY(-480px);
  }
}
@keyframes scroll2 {
  from {
    transform: translateY(-240px);
    left: 0;
  }
  to {
    transform: translateY(-720px);
  }
}
.test1 {
  animation: scroll1 12s linear 0s infinite;
  margin-top: 120px;
}
.test2 {
  animation: scroll2 12s linear 6s infinite;
  transform: translateY(-240px);
}

4.監(jiān)聽(tīng)card塊,當(dāng)card塊移出視窗時(shí),觸發(fā)dom節(jié)點(diǎn)刷新。監(jiān)聽(tīng)使用IntersectionObserver這個(gè)api。

@keyframes scroll1 {
  from {
    transform: translateY(0);
    left: 0;
  }
  to {
    transform: translateY(-480px);
  }
}
@keyframes scroll2 {
  from {
    transform: translateY(-240px);
    left: 0;
  }
  to {
    transform: translateY(-720px);
  }
}
.test1 {
  animation: scroll1 12s linear 0s infinite;
  margin-top: 120px;
}
.test2 {
  animation: scroll2 12s linear 6s infinite;
  transform: translateY(-240px);
}

完整代碼

以下為完整代碼:

<template>
  <div class="wrapper">
    <div class="container">
      <div class="test1" id="card1">
        <div class="content" v-for="item in cardArr1" :key="item">
          <img class="image" src="https://static-legacy.dingtalk.com/media/lADPDhmOwd9ZBQXNA8DNA8A_960_960.jpg"
          alt="" />
          <span>
            {{ item }}已獲得500元京東卡
          </span>
        </div>
      </div>
      <div class="test2" id="card2">
        <div class="content" v-for="item in cardArr2" :key="item">
          <img class="image" src="https://static-legacy.dingtalk.com/media/lADPDhmOwd9ZBQXNA8DNA8A_960_960.jpg"
          alt="" />
          <span>
            {{ item }}已獲得100元京東卡
          </span>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
  import { ref, defineComponent, onMounted } from "vue";
  
  export default defineComponent({
    setup() {
      let firsrObserver = true;
      let data: any = [];
      for (let i = 1; i <= 10; i++) {
        data.push(i);
      }
      const cardArr1 = ref<Array<any>>(data.slice(0, 3));
      const cardArr2 = ref<Array<any>>(data.slice(3, 6));
      console.log(cardArr1.value, cardArr2.value);
      
      let currentIndex = 6;
      const getNewData = () => {
        if (currentIndex + 3 <= data.length) {
          return data.slice(currentIndex, (currentIndex = currentIndex + 3));
        } else {
          let rst = data.slice(currentIndex);
          currentIndex = 3 - rst.length;
          Array.prototype.push.apply(rst, data.slice(0, currentIndex));
          return rst;
        }
      };
      const observer2 = new IntersectionObserver((entry: any) => {
        // 第三第四第五加載新數(shù)據(jù)
        if (!entry[0].isIntersecting) {
          console.log(entry);
          if (entry[0].target.id === "card1") {
            cardArr1.value.splice(0, 3, ...getNewData());
          } else {
            cardArr2.value.splice(0, 3, ...getNewData());
          }
          console.log(cardArr1.value, cardArr2.value);
        }
        firsrObserver = false;
      });
      onMounted(() => {
        observer2.observe(document.getElementById("card1") as HTMLElement);
        observer2.observe(document.getElementById("card2") as HTMLElement);
      });
      return {
        data,
        cardArr1,
        cardArr2,
      };
    },
  });
</script>
<style scoped>
  .wrapper {
    height: 500px;
    display: flex;
    align-items: center;
    /* background: pink; */
    justify-content: center;
  }
  .container {
    width: 300px;
    height: 120px;
    overflow: hidden;
    background: #ccc;
  }
  .test1 {
    animation: scroll1 12s linear 0s infinite;
    margin-top: 120px;
  }
  .test2 {
    animation: scroll2 12s linear 6s infinite;
    transform: translateY(-240px);
  }
  .content {
    width: 290px;
    height: 56px;
    display: flex;
    margin: 24px auto;
    background: #fff;
    border-radius: 100px;
    flex-flow: row nowrap;
    align-items: center;
    backdrop-filter: blur(4px);
  }
  .image {
    width: 36px;
    height: 36px;
    margin: auto 10px;
    border-radius: 100%;
  }
  span {
    font-family: PingFang SC;
    font-size: 20px;
    line-height: 20px;
    text-align: center;
  }
  @keyframes scroll1 {
    from {
      transform: translateY(0);
      left: 0;
    }
    to {
      transform: translateY(-480px);
    }
  }
  @keyframes scroll2 {
    from {
      transform: translateY(-240px);
      left: 0;
    }
    to {
      transform: translateY(-720px);
    }
  }
</style>

效果展示:

以上就是基于Vue實(shí)現(xiàn)實(shí)現(xiàn)卡片無(wú)限滾動(dòng)動(dòng)畫的詳細(xì)內(nèi)容,更多關(guān)于Vue無(wú)限滾動(dòng)動(dòng)畫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue3解析markdown并實(shí)現(xiàn)代碼高亮顯示的詳細(xì)步驟

    Vue3解析markdown并實(shí)現(xiàn)代碼高亮顯示的詳細(xì)步驟

    Vue的markdown解析庫(kù)有很多,如markdown-it、vue-markdown-loader、marked、vue-markdown等,這篇文章主要介紹了Vue3解析markdown并實(shí)現(xiàn)代碼高亮顯示,需要的朋友可以參考下
    2022-07-07
  • vue加載完成后的回調(diào)函數(shù)方法

    vue加載完成后的回調(diào)函數(shù)方法

    今天小編就為大家分享一篇vue加載完成后的回調(diào)函數(shù)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • 詳解vue 在移動(dòng)端體驗(yàn)上的優(yōu)化解決方案

    詳解vue 在移動(dòng)端體驗(yàn)上的優(yōu)化解決方案

    這篇文章主要介紹了vue 在移動(dòng)端體驗(yàn)上的優(yōu)化解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • vue實(shí)現(xiàn)todolist基本功能以及數(shù)據(jù)存儲(chǔ)功能實(shí)例詳解

    vue實(shí)現(xiàn)todolist基本功能以及數(shù)據(jù)存儲(chǔ)功能實(shí)例詳解

    本文通過(guò)實(shí)例代碼給大家介紹了vue實(shí)現(xiàn)todolist基本功能以及數(shù)據(jù)存儲(chǔ)功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • v-slot和slot、slot-scope之間相互替換實(shí)例

    v-slot和slot、slot-scope之間相互替換實(shí)例

    這篇文章主要介紹了v-slot和slot、slot-scope之間相互替換實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Vue中子組件不能修改父組件傳來(lái)的Prop值的原因分析

    Vue中子組件不能修改父組件傳來(lái)的Prop值的原因分析

    在Vue中,父子組件之間通過(guò)Prop和Event實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定,但是,Vue設(shè)計(jì)者為什么不允許子組件修改父組件傳遞的Prop呢,本文就來(lái)帶大家探究為什么子組件不能修改Prop,需要的朋友可以參考下
    2023-06-06
  • vue自定義keepalive組件的問(wèn)題解析

    vue自定義keepalive組件的問(wèn)題解析

    這篇文章主要介紹了vue自定義keepalive組件的相關(guān)資料,keep-alive組件是使用?include?exclude這兩個(gè)屬性傳入組件名稱來(lái)確認(rèn)哪些可以被緩存的,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-07-07
  • vue報(bào)錯(cuò)Failed to execute 'appendChild' on 'Node'解決

    vue報(bào)錯(cuò)Failed to execute 'appendChild&apos

    這篇文章主要為大家介紹了vue報(bào)錯(cuò)Failed to execute 'appendChild' on 'Node'解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Vue倒計(jì)時(shí)3秒后返回首頁(yè)Demo(推薦)

    Vue倒計(jì)時(shí)3秒后返回首頁(yè)Demo(推薦)

    這篇文章主要介紹了Vue倒計(jì)時(shí)3秒后返回首頁(yè)Demo,倒計(jì)時(shí)結(jié)束后要清除計(jì)時(shí)器,防止內(nèi)存泄漏,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-11-11
  • vue3數(shù)據(jù)監(jiān)聽(tīng)watch/watchEffect的示例代碼

    vue3數(shù)據(jù)監(jiān)聽(tīng)watch/watchEffect的示例代碼

    我們都知道監(jiān)聽(tīng)器的作用是在每次響應(yīng)式狀態(tài)發(fā)生變化時(shí)觸發(fā),在組合式?API?中,我們可以使用?watch()函數(shù)和watchEffect()函數(shù),下面我們來(lái)看下vue3如何進(jìn)行數(shù)據(jù)監(jiān)聽(tīng)watch/watchEffect,感興趣的朋友一起看看吧
    2023-02-02

最新評(píng)論