溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue怎么實(shí)現(xiàn)書本翻頁動畫效果

發(fā)布時間:2022-04-08 10:24:21 來源:億速云 閱讀:649 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“vue怎么實(shí)現(xiàn)書本翻頁動畫效果”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“vue怎么實(shí)現(xiàn)書本翻頁動畫效果”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

效果如下:

vue怎么實(shí)現(xiàn)書本翻頁動畫效果

關(guān)鍵字

transform

Transform屬性應(yīng)用于元素的2D或3D轉(zhuǎn)換。這個屬性允許你將元素旋轉(zhuǎn),縮放,移動,傾斜等。

語法為transform: none|*transform-functions*; 我們主要使用到其旋轉(zhuǎn)效果,我們可以這樣寫。

transform: rotateY(90deg)
//表示沿Y軸旋轉(zhuǎn)90度

animation

既然是要實(shí)現(xiàn)動畫效果,那么肯定少不了animation的出場了,

animation屬性的語法為: animation: name duration timing-function delay iteration-count direction fill-mode play-state;我們需要用到的只是前兩個屬性,name和duration,分別為指定要綁定到選擇器的關(guān)鍵幀的名稱動畫指定需要多少秒或毫秒完成 我們可以這樣寫

animation: fanPre 2s;

@keyframes

使用@keyframes規(guī)則,你可以創(chuàng)建動畫,創(chuàng)建動畫是通過逐步改變從一個CSS樣式設(shè)定到另一個,在動畫過程中,可以更改CSS樣式的設(shè)定多次,指定的變化時發(fā)生時使用%,或關(guān)鍵字"from"和"to",這是和0%到100%相同。

語法為:@keyframes *animationname* {*keyframes-selector* {*css-styles;}* } 我們可以這樣寫

@keyframes fanPre {
  0% {
    transform: rotateY(0deg);
    background-color: rgba(122, 112, 112);
  }
  50% {
    background-color: rgba(122, 112, 112);
  }
  75% {
    background-color: rgba(122, 112, 112);
  }
  100% {
    transform: rotateY(-140deg);
    background-color: none;
  }
}

var

此var并不是JavaScript中的var而是css中的var,我們可以使用其來實(shí)現(xiàn)css與vue數(shù)據(jù)繼續(xù)數(shù)據(jù)交換,及css中可以使用vue定義的data來進(jìn)行屬性設(shè)置,具體如下:

//html
<div :></div>
//javascript
props: {
    speed: {
      type: String,
      default: "2s",
    }
}
//css
<style vars="{ speed, degs }" lang="scss" scoped>
    animation: fanPre var(--speed);
</style>

實(shí)現(xiàn)

知道了上面這幾個關(guān)鍵詞之后,我們便可以開始著手實(shí)現(xiàn)該效果了,首先我們需要一個書本頁面列表數(shù)據(jù)

//書本頁面列表
    pagesList: {
      type: Array,
      default: () => {
        return [
          {
            title: "關(guān)雎",
            text: [
              "關(guān)關(guān)雎鳩,在河之洲。窈窕淑女,君子好逑。",
              "參差荇菜,左右流之。窈窕淑女,寤寐求之。",
              "求之不得,寤寐思服。悠哉悠哉,輾轉(zhuǎn)反側(cè)。",
              "參差荇菜,左右采之。窈窕淑女,琴瑟友之。",
              "參差荇菜,左右芼之。窈窕淑女,鐘鼓樂之。",
            ],
          },
          {
            title: "聲聲慢·尋尋覓覓",
            text: [
              "尋尋覓覓,冷冷清清,凄凄慘慘戚戚。乍暖還寒時候,最難將息。三杯兩盞淡酒,怎敵他、晚來風(fēng)急!雁過也,正傷心,卻是舊時相識。",
              "滿地黃花堆積,憔悴損,如今有誰堪摘?守著窗兒,獨(dú)自怎生得黑!梧桐更兼細(xì)雨,到黃昏、點(diǎn)點(diǎn)滴滴。這次第,怎一個愁字了得!",
            ],
          },
          {
            title: "青玉案·元夕",
            text: [
              "東風(fēng)夜放花千樹。更吹落、星如雨。寶馬雕車香滿路。鳳簫聲動,玉壺光轉(zhuǎn),一夜魚龍舞。",
              "蛾兒雪柳黃金縷。笑語盈盈暗香去。眾里尋他千百度。驀然回首,那人卻在,燈火闌珊處。",
            ],
          },
          {
            title: "蝶戀花·佇倚危樓風(fēng)細(xì)細(xì)",
            text: [
              "佇倚危樓風(fēng)細(xì)細(xì),望極春愁,黯黯生天際。草色煙光殘照里,無言誰會憑闌意。",
              "擬把疏狂圖一醉,對酒當(dāng)歌,強(qiáng)樂還無味。衣帶漸寬終不悔,為伊消得人憔悴。",
            ],
          },
          {
            title: "雨霖鈴·秋別",
            text: [
              "寒蟬凄切,對長亭晚,驟雨初歇。都門帳飲無緒,留戀處,蘭舟催發(fā)。執(zhí)手相看淚眼,竟無語凝噎。念去去,千里煙波,暮靄沉沉楚天闊。",
              "多情自古傷離別,更那堪,冷落清秋節(jié)!今宵酒醒何處?楊柳岸,曉風(fēng)殘?jiān)?。此去?jīng)年,應(yīng)是良辰好景虛設(shè)。便縱有千種風(fēng)情,更與何人說",
            ],
          },
        ];
      },
    },

將數(shù)據(jù)渲染到頁面上,如下例子

<div
    @click="turnPage(1)"
    class="j-book-page"
    :key="'page-now-' + index"
    :
>
    <h4>{{ nowPage.title }}</h4>
    <p
      v-for="(t, nowPageInd) in nowPage.text"
      :key="'nowPage-' + nowPageInd"
    >
      {{ t }}
    </p>
</div>

頁面翻頁功能實(shí)現(xiàn)如下,使用currentPage來記錄當(dāng)前展示頁面頁數(shù),使用flag來區(qū)分是上一頁還是下一頁翻頁,并進(jìn)行相應(yīng)的翻頁操作。其中要注意對點(diǎn)擊事件進(jìn)行防抖操作,防止翻頁過快,具體代碼如下:

    turnPage(flag) {
      if (!this.canTurn) return;
      if (this.currentPage <= this.pagesList.length)
        this.setPage(this.currentPage, flag);
      if (this.currentPage < this.pagesList.length && this.currentPage > 0) {
        this.canTurn = false;
        setTimeout(() => {
          this.canTurn = true;
        }, parseInt(this.speed) * 1000 - 100);
      }
      if (flag === 1) {
        if (this.currentPage < this.pagesList.length) {
          this.currentPage++;
          this.nextClick = true;
          this.lastClick = false;
        }
      } else {
        if (this.currentPage > 0) {
          this.currentPage--;
          this.nextClick = false;
          this.lastClick = true;
        }
      }
    },

完整代碼

<template>
  <div class="j-book" :>
    <div :>
      <div
        class="j-book-page-pre"
        @click="turnPage(-1)"
        v-if="currentPage > 0 && showCover"
      >
        <div class="j-book-page">
          <h4>{{ prePage.title }}</h4>
          <p v-for="(t, textInd) in prePage.text" :key="'prePage-' + textInd">
            {{ t }}
          </p>
        </div>
      </div>
      <div class="j-book-pages">
        <template v-for="(item, index) in pagesList">
          <div
            @click="turnPage(-1)"
            class="j-book-page turn-page-ani"
            v-if="currentPage === index + 2 && nextClick"
            :key="'page-last--' + index"
            :
          >
            <h4>{{ item.title }}</h4>
            <p v-for="(t, itemInd) in item.text" :key="'item-' + itemInd">
              {{ t }}
            </p>
          </div>
          <div
            @click="turnPage(-1)"
            class="j-book-page turn-page-ani"
            v-if="currentPage === 1 && nextClick"
            :key="'page-last-' + index"
            :
          >
            <h4>{{ cover.title }}</h4>
            <p v-for="(t, coverInd) in cover.text" :key="'cover-' + coverInd">
              {{ t }}
            </p>
          </div>
          <div
            @click="turnPage(1)"
            class="j-book-page turn-page-pre-ani"
            v-if="lastClick && currentPage === 0"
            :key="'page-pre-currentPage' + index"
            :
          >
            <h4>{{ cover.title }}</h4>
            <p v-for="(t, coverInd) in cover.text" :key="'cover-0-' + coverInd">
              {{ t }}
            </p>
          </div>
          <div
            @click="turnPage(1)"
            class="j-book-page turn-page-pre-ani"
            v-if="lastClick && currentPage === index + 1"
            :key="'page-pre-' + index"
            :
          >
            <h4>{{ item.title }}</h4>
            <p v-for="(t, itemInd) in item.text" :key="'item-0-' + itemInd">
              {{ t }}
            </p>
          </div>
          <div
            @click="turnPage(1)"
            class="j-book-page"
            :key="'page-now-' + index"
            :
          >
            <h4>{{ nowPage.title }}</h4>
            <p
              v-for="(t, nowPageInd) in nowPage.text"
              :key="'nowPage-' + nowPageInd"
            >
              {{ t }}
            </p>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "book",
  props: {
    width: {
      type: Number,
      default: 300,
    },
    height: {
      type: Number,
      default: 400,
    },
    speed: {
      type: String,
      default: "2s",
    },
    //書本頁面列表
    pagesList: {
      type: Array,
      default: () => {
        return [
          {
            title: "關(guān)雎",
            text: [
              "關(guān)關(guān)雎鳩,在河之洲。窈窕淑女,君子好逑。",
              "參差荇菜,左右流之。窈窕淑女,寤寐求之。",
              "求之不得,寤寐思服。悠哉悠哉,輾轉(zhuǎn)反側(cè)。",
              "參差荇菜,左右采之。窈窕淑女,琴瑟友之。",
              "參差荇菜,左右芼之。窈窕淑女,鐘鼓樂之。",
            ],
          },
          {
            title: "聲聲慢·尋尋覓覓",
            text: [
              "尋尋覓覓,冷冷清清,凄凄慘慘戚戚。乍暖還寒時候,最難將息。三杯兩盞淡酒,怎敵他、晚來風(fēng)急!雁過也,正傷心,卻是舊時相識。",
              "滿地黃花堆積,憔悴損,如今有誰堪摘?守著窗兒,獨(dú)自怎生得黑!梧桐更兼細(xì)雨,到黃昏、點(diǎn)點(diǎn)滴滴。這次第,怎一個愁字了得!",
            ],
          },
          {
            title: "青玉案·元夕",
            text: [
              "東風(fēng)夜放花千樹。更吹落、星如雨。寶馬雕車香滿路。鳳簫聲動,玉壺光轉(zhuǎn),一夜魚龍舞。",
              "蛾兒雪柳黃金縷。笑語盈盈暗香去。眾里尋他千百度。驀然回首,那人卻在,燈火闌珊處。",
            ],
          },
          {
            title: "蝶戀花·佇倚危樓風(fēng)細(xì)細(xì)",
            text: [
              "佇倚危樓風(fēng)細(xì)細(xì),望極春愁,黯黯生天際。草色煙光殘照里,無言誰會憑闌意。",
              "擬把疏狂圖一醉,對酒當(dāng)歌,強(qiáng)樂還無味。衣帶漸寬終不悔,為伊消得人憔悴。",
            ],
          },
          {
            title: "雨霖鈴·秋別",
            text: [
              "寒蟬凄切,對長亭晚,驟雨初歇。都門帳飲無緒,留戀處,蘭舟催發(fā)。執(zhí)手相看淚眼,竟無語凝噎。念去去,千里煙波,暮靄沉沉楚天闊。",
              "多情自古傷離別,更那堪,冷落清秋節(jié)!今宵酒醒何處?楊柳岸,曉風(fēng)殘?jiān)?。此去?jīng)年,應(yīng)是良辰好景虛設(shè)。便縱有千種風(fēng)情,更與何人說",
            ],
          },
        ];
      },
    },
    //書本封面
    cover: {
      type: Object,
      default: () => {
        return {
          title: "封面",
          text: ["封面"],
        };
      },
    },
  },
  data() {
    return {
      currentPage: 0,
      nextClick: false,
      lastClick: false,
      prePage: {},
      nowPage: {},
      canTurn: true,
      degs: "0deg",
      showCover: false,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.nowPage = this.cover;
    },
    getBookStyle() {
      let res = "";
      res += "width:" + this.width + "px;";
      res += "height:" + this.height + "px;";
      res += "'--speed':" + this.speed + ";";
      res += "transform: rotate(" + this.degs + ");";
      return res;
    },
    getPageStyle(index) {
      let res = "";
      res += "z-index:" + (this.pagesList.length - index) + ";";
      return res;
    },
    setPage(page, flag) {
      if (flag === -1) {
        this.prePage = this.pagesList[page - 3] || this.cover;
        this.nowPage = this.pagesList[page - 1];
      } else {
        this.prePage = this.pagesList[page - 2] || this.cover;
        this.nowPage =
          this.pagesList[ page ] || this.pagesList[this.pagesList.length - 1];
      }
      let speed = this.speed;
      speed = parseInt(speed) * 1000 - 500;
      setTimeout(() => {
        if (this.currentPage === 1) {
          this.showCover = true;
        }
        if (this.currentPage === 0) {
          this.showCover = false;
        }
        if (flag === -1) {
          this.nowPage = this.pagesList[this.currentPage - 1] || this.cover;
          if (this.currentPage === 0) {
            this.degs = "0deg";
          }
        } else {
          this.degs = "-5deg";
          this.prePage = this.pagesList[this.currentPage - 2] || this.cover;
        }
      }, speed);
    },
    turnPage(flag) {
      if (!this.canTurn) return;
      if (this.currentPage <= this.pagesList.length)
        this.setPage(this.currentPage, flag);
      if (this.currentPage < this.pagesList.length && this.currentPage > 0) {
        this.canTurn = false;
        setTimeout(() => {
          this.canTurn = true;
        }, parseInt(this.speed) * 1000 - 100);
      }
      if (flag === 1) {
        if (this.currentPage < this.pagesList.length) {
          this.currentPage++;
          this.nextClick = true;
          this.lastClick = false;
        }
      } else {
        if (this.currentPage > 0) {
          this.currentPage--;
          this.nextClick = false;
          this.lastClick = true;
        }
      }
    },
  },
};
</script>

<style vars="{ speed, degs }" lang="scss" scoped>
.j-book {
  background-color: gray;
  position: relative;
  box-shadow: 30px 0px 30px rgb(0, 0, 0, 0.6) inset;
  transform: rotate(var(--degs));
  color: #dec38f;
  .j-book-page-pre {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 2;
    background-size: 100%;
    transform-origin: left;
    border-top-left-radius: 2px;
    border-bottom-left-radius: 2px;
    background-color: rgba(122, 112, 112);
    transform: rotateY(-140deg);
    .j-book-page {
      position: absolute;
      width: 100%;
      height: 100%;
    }
  }
  .j-book-pages {
    position: absolute;
    width: 100%;
    height: 100%;

    .turn-page-pre-ani {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 2;
      background-size: 100%;
      transform-origin: left;
      border-top-left-radius: 2px;
      border-bottom-left-radius: 2px;
      transform: rotateY(0deg);
      animation: fanPre var(--speed);
    }
    @keyframes fanPre {
      0% {
        transform: rotateY(-140deg);
        background-color: rgba(122, 112, 112);
      }
      50% {
        background-color: rgba(122, 112, 112);
      }
      100% {
        transform: rotateY(0deg);
        background-color: none;
      }
    }
    .turn-page-ani {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 2;
      background-size: 100%;
      transform-origin: left;
      border-top-left-radius: 2px;
      border-bottom-left-radius: 2px;
      transform: rotateY(-140deg);
      animation: fan var(--speed);
    }
    @keyframes fan {
      0% {
        transform: rotateY(0deg);
        background-color: none;
      }
      100% {
        transform: rotateY(-140deg);
        background-color: rgba(122, 112, 112);
      }
    }
    .j-book-page {
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      h4 {
        text-align: center;
      }
      p {
      }
    }
  }
  .j-book-btns {
    position: absolute;
    bottom: 0;
    display: flex;
    justify-content: space-around;
    width: 100%;
  }
}
</style>

讀到這里,這篇“vue怎么實(shí)現(xiàn)書本翻頁動畫效果”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

vue
AI