您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“vue怎么實(shí)現(xiàn)書本翻頁動畫效果”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“vue怎么實(shí)現(xiàn)書本翻頁動畫效果”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。
效果如下:
Transform屬性應(yīng)用于元素的2D或3D轉(zhuǎn)換。這個屬性允許你將元素旋轉(zhuǎn),縮放,移動,傾斜等。
語法為transform: none|*transform-functions*;
我們主要使用到其旋轉(zhuǎn)效果,我們可以這樣寫。
transform: rotateY(90deg) //表示沿Y軸旋轉(zhuǎn)90度
既然是要實(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規(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并不是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>
知道了上面這幾個關(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è)資訊頻道。
免責(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)容。