您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“vue怎么實現書本翻頁動畫效果”,內容詳細,步驟清晰,細節處理妥當,希望這篇“vue怎么實現書本翻頁動畫效果”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
效果如下:
Transform屬性應用于元素的2D或3D轉換。這個屬性允許你將元素旋轉,縮放,移動,傾斜等。
語法為transform: none|*transform-functions*;
我們主要使用到其旋轉效果,我們可以這樣寫。
transform: rotateY(90deg) //表示沿Y軸旋轉90度
既然是要實現動畫效果,那么肯定少不了animation的出場了,
animation屬性的語法為: animation: name duration timing-function delay iteration-count direction fill-mode play-state;
我們需要用到的只是前兩個屬性,name和duration,分別為指定要綁定到選擇器的關鍵幀的名稱和動畫指定需要多少秒或毫秒完成 我們可以這樣寫
animation: fanPre 2s;
使用@keyframes規則,你可以創建動畫,創建動畫是通過逐步改變從一個CSS樣式設定到另一個,在動畫過程中,可以更改CSS樣式的設定多次,指定的變化時發生時使用%,或關鍵字"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并不是JavaScript中的var而是css中的var,我們可以使用其來實現css與vue數據繼續數據交換,及css中可以使用vue定義的data來進行屬性設置,具體如下:
//html <div :></div> //javascript props: { speed: { type: String, default: "2s", } } //css <style vars="{ speed, degs }" lang="scss" scoped> animation: fanPre var(--speed); </style>
知道了上面這幾個關鍵詞之后,我們便可以開始著手實現該效果了,首先我們需要一個書本頁面列表數據
//書本頁面列表 pagesList: { type: Array, default: () => { return [ { title: "關雎", text: [ "關關雎鳩,在河之洲。窈窕淑女,君子好逑。", "參差荇菜,左右流之。窈窕淑女,寤寐求之。", "求之不得,寤寐思服。悠哉悠哉,輾轉反側。", "參差荇菜,左右采之。窈窕淑女,琴瑟友之。", "參差荇菜,左右芼之。窈窕淑女,鐘鼓樂之。", ], }, { title: "聲聲慢·尋尋覓覓", text: [ "尋尋覓覓,冷冷清清,凄凄慘慘戚戚。乍暖還寒時候,最難將息。三杯兩盞淡酒,怎敵他、晚來風急!雁過也,正傷心,卻是舊時相識。", "滿地黃花堆積,憔悴損,如今有誰堪摘?守著窗兒,獨自怎生得黑!梧桐更兼細雨,到黃昏、點點滴滴。這次第,怎一個愁字了得!", ], }, { title: "青玉案·元夕", text: [ "東風夜放花千樹。更吹落、星如雨。寶馬雕車香滿路。鳳簫聲動,玉壺光轉,一夜魚龍舞。", "蛾兒雪柳黃金縷。笑語盈盈暗香去。眾里尋他千百度。驀然回首,那人卻在,燈火闌珊處。", ], }, { title: "蝶戀花·佇倚危樓風細細", text: [ "佇倚危樓風細細,望極春愁,黯黯生天際。草色煙光殘照里,無言誰會憑闌意。", "擬把疏狂圖一醉,對酒當歌,強樂還無味。衣帶漸寬終不悔,為伊消得人憔悴。", ], }, { title: "雨霖鈴·秋別", text: [ "寒蟬凄切,對長亭晚,驟雨初歇。都門帳飲無緒,留戀處,蘭舟催發。執手相看淚眼,竟無語凝噎。念去去,千里煙波,暮靄沉沉楚天闊。", "多情自古傷離別,更那堪,冷落清秋節!今宵酒醒何處?楊柳岸,曉風殘月。此去經年,應是良辰好景虛設。便縱有千種風情,更與何人說", ], }, ]; }, },
將數據渲染到頁面上,如下例子
<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>
頁面翻頁功能實現如下,使用currentPage來記錄當前展示頁面頁數,使用flag來區分是上一頁還是下一頁翻頁,并進行相應的翻頁操作。其中要注意對點擊事件進行防抖操作,防止翻頁過快,具體代碼如下:
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: "關雎", text: [ "關關雎鳩,在河之洲。窈窕淑女,君子好逑。", "參差荇菜,左右流之。窈窕淑女,寤寐求之。", "求之不得,寤寐思服。悠哉悠哉,輾轉反側。", "參差荇菜,左右采之。窈窕淑女,琴瑟友之。", "參差荇菜,左右芼之。窈窕淑女,鐘鼓樂之。", ], }, { title: "聲聲慢·尋尋覓覓", text: [ "尋尋覓覓,冷冷清清,凄凄慘慘戚戚。乍暖還寒時候,最難將息。三杯兩盞淡酒,怎敵他、晚來風急!雁過也,正傷心,卻是舊時相識。", "滿地黃花堆積,憔悴損,如今有誰堪摘?守著窗兒,獨自怎生得黑!梧桐更兼細雨,到黃昏、點點滴滴。這次第,怎一個愁字了得!", ], }, { title: "青玉案·元夕", text: [ "東風夜放花千樹。更吹落、星如雨。寶馬雕車香滿路。鳳簫聲動,玉壺光轉,一夜魚龍舞。", "蛾兒雪柳黃金縷。笑語盈盈暗香去。眾里尋他千百度。驀然回首,那人卻在,燈火闌珊處。", ], }, { title: "蝶戀花·佇倚危樓風細細", text: [ "佇倚危樓風細細,望極春愁,黯黯生天際。草色煙光殘照里,無言誰會憑闌意。", "擬把疏狂圖一醉,對酒當歌,強樂還無味。衣帶漸寬終不悔,為伊消得人憔悴。", ], }, { title: "雨霖鈴·秋別", text: [ "寒蟬凄切,對長亭晚,驟雨初歇。都門帳飲無緒,留戀處,蘭舟催發。執手相看淚眼,竟無語凝噎。念去去,千里煙波,暮靄沉沉楚天闊。", "多情自古傷離別,更那堪,冷落清秋節!今宵酒醒何處?楊柳岸,曉風殘月。此去經年,應是良辰好景虛設。便縱有千種風情,更與何人說", ], }, ]; }, }, //書本封面 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怎么實現書本翻頁動畫效果”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。