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

vue實(shí)現(xiàn)書本翻頁動(dòng)畫效果實(shí)例詳解

 更新時(shí)間:2022年04月08日 09:30:34   作者:JYeontu  
這篇文章主要介紹了vue簡單實(shí)現(xiàn)書本翻頁效果,需要的朋友可以參考下

偶然興起,想要用vue來做一個(gè)書本的組件,有了這個(gè)想法后邊開始動(dòng)手,先簡單地實(shí)現(xiàn)基本的效果,為后續(xù)封裝為組件進(jìn)行準(zhǔn)備工作,實(shí)現(xiàn)該效果的要使用vue + css + JavaScript。

關(guān)鍵字

transform

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

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

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

animation

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

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

animation: fanPre 2s;

@keyframes

使用@keyframes規(guī)則,你可以創(chuàng)建動(dòng)畫,創(chuàng)建動(dòng)畫是通過逐步改變從一個(gè)CSS樣式設(shè)定到另一個(gè),在動(dòng)畫過程中,可以更改CSS樣式的設(shè)定多次,指定的變化時(shí)發(fā)生時(shí)使用%,或關(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 :style="{ '--speed': speed }"></div>
//javascript
props: {
    speed: {
      type: String,
      default: "2s",
    }
}
//css
<style vars="{ speed, degs }" lang="scss" scoped>
    animation: fanPre var(--speed);
</style>

實(shí)現(xiàn)

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

//書本頁面列表
    pagesList: {
      type: Array,
      default: () => {
        return [
          {
            title: "關(guān)雎",
            text: [
              "關(guān)關(guān)雎鳩,在河之洲。窈窕淑女,君子好逑。",
              "參差荇菜,左右流之。窈窕淑女,寤寐求之。",
              "求之不得,寤寐思服。悠哉悠哉,輾轉(zhuǎn)反側(cè)。",
              "參差荇菜,左右采之。窈窕淑女,琴瑟友之。",
              "參差荇菜,左右芼之。窈窕淑女,鐘鼓樂之。",
            ],
          },
          {
            title: "聲聲慢·尋尋覓覓",
            text: [
              "尋尋覓覓,冷冷清清,凄凄慘慘戚戚。乍暖還寒時(shí)候,最難將息。三杯兩盞淡酒,怎敵他、晚來風(fēng)急!雁過也,正傷心,卻是舊時(shí)相識。",
              "滿地黃花堆積,憔悴損,如今有誰堪摘?守著窗兒,獨(dú)自怎生得黑!梧桐更兼細(xì)雨,到黃昏、點(diǎn)點(diǎn)滴滴。這次第,怎一個(gè)愁字了得!",
            ],
          },
          {
            title: "青玉案·元夕",
            text: [
              "東風(fēng)夜放花千樹。更吹落、星如雨。寶馬雕車香滿路。鳳簫聲動(dò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"
    :style="getPageStyle(index)"
>
    <h3>{{ nowPage.title }}</h3>
    <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" :style="getBookStyle()">
    <div :style="{ '--speed': speed, '--degs': degs }">
      <div
        class="j-book-page-pre"
        @click="turnPage(-1)"
        v-if="currentPage > 0 && showCover"
      >
        <div class="j-book-page">
          <h3>{{ prePage.title }}</h3>
          <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"
            :style="getPageStyle(index)"
          >
            <h3>{{ item.title }}</h3>
            <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"
            :style="getPageStyle(index)"
          >
            <h3>{{ cover.title }}</h3>
            <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"
            :style="getPageStyle(5)"
          >
            <h3>{{ cover.title }}</h3>
            <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"
            :style="getPageStyle(5)"
          >
            <h3>{{ item.title }}</h3>
            <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"
            :style="getPageStyle(index)"
          >
            <h3>{{ nowPage.title }}</h3>
            <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: [
              "尋尋覓覓,冷冷清清,凄凄慘慘戚戚。乍暖還寒時(shí)候,最難將息。三杯兩盞淡酒,怎敵他、晚來風(fēng)急!雁過也,正傷心,卻是舊時(shí)相識。",
              "滿地黃花堆積,憔悴損,如今有誰堪摘?守著窗兒,獨(dú)自怎生得黑!梧桐更兼細(xì)雨,到黃昏、點(diǎn)點(diǎn)滴滴。這次第,怎一個(gè)愁字了得!",
            ],
          },
          {
            title: "青玉案·元夕",
            text: [
              "東風(fēng)夜放花千樹。更吹落、星如雨。寶馬雕車香滿路。鳳簫聲動(dò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)隆4巳ソ?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;
      h3 {
        text-align: center;
      }
      p {
      }
    }
  }
  .j-book-btns {
    position: absolute;
    bottom: 0;
    display: flex;
    justify-content: space-around;
    width: 100%;
  }
}
</style>

更多關(guān)于VUE特效請查看下面的相關(guān)鏈接

相關(guān)文章

最新評論