Vue 優(yōu)雅的實(shí)現(xiàn)移動(dòng)端過場動(dòng)畫

前言

在做移動(dòng)端項(xiàng)目的時(shí)候,每次進(jìn)行push操作,頁面都是一閃切到下個(gè)界面,整個(gè)體驗(yàn)十分H5,尤其是嵌入APP的Hybrid項(xiàng)目,這種體驗(yàn)很容易讓用戶發(fā)覺這是一個(gè)H5頁面,那我們怎么樣才能解決這種突兀的轉(zhuǎn)場呢?

思考

之前用過ionic3開發(fā)過一些項(xiàng)目,為了支持APP的熱更新功能
作為UI框架,他們在過場動(dòng)畫方面下足了功夫,讓整個(gè)APP體驗(yàn)提升了不少
所以我也希望可以在vue項(xiàng)目中加入絲滑的過場動(dòng)畫,來承上啟下

剛好Vue官方也提供了專門處理動(dòng)畫的<transition>組件
我們就嘗試用該組件來完成頁面的轉(zhuǎn)場動(dòng)畫

動(dòng)畫形式主要參考iOS系統(tǒng)push頁面時(shí)的過渡效果

iOS過場動(dòng)畫效果

解決方案

代碼樣例依賴:

"vue": "^3.0.5",
"vue-router": "^4.0.11"
"vite": "^2.4.4"

1、動(dòng)畫部分解析

  • A -> B , A在下,B在上,且B左側(cè)增加陰影
    A從(0, 0)向左移50%
    B從(0, 100%)向左移100%

  • B -> A , A在下,B在上,且B左側(cè)增加陰影
    A從(-50%, 0)向右移50%
    B從(0, 0)向右移100%

  • 整個(gè)動(dòng)畫過程是有漸變蒙版,以及動(dòng)畫的貝塞爾曲線,這里忽略蒙版變化,貝塞爾也選擇常用的內(nèi)置ease-out

2、實(shí)現(xiàn)動(dòng)畫內(nèi)容

  • css部分:按照上面分解的內(nèi)容,可以較容易的實(shí)現(xiàn)

這里有幾個(gè)遇到的坑:
1、頁面切換動(dòng)畫執(zhí)行from頁面白屏
因?yàn)槭俏臋n流的原因,老頁面被新頁面擠到下面去了,所以使用absolute讓其定位到應(yīng)該出現(xiàn)的位置

2、陰影設(shè)置的問題
需要在初始狀態(tài)和active狀態(tài)都設(shè)置陰影,以避免陰影出現(xiàn)漸變

.slide-right-enter-active,
.slide-left-enter-active,
.slide-right-leave-active,
.slide-left-leave-active {
    /* 這里保持動(dòng)畫過程中的陰影 */
    box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
    will-change: transform;
    transition: all 0.5s ease-out;
    /* 這里為了解決入棧出棧時(shí)的白屏現(xiàn)象 */
    position: absolute;
}


.slide-right-enter-from {
    /* 這里設(shè)置0,為了避免一開始頁面內(nèi)容一閃而過的情況 */
    opacity: 0;
    transform: translateX(-50%);
}
.slide-right-leave-to {
    z-index: 100;
    /* 這里為了優(yōu)化陰影溢出屏幕,不至于突然消失 */
    transform: translateX(102%); 
}
.slide-right-leave-from {
    box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
}


.slide-left-enter-from {
    z-index: 100;
    transform: translateX(100%);
    box-shadow: -20px 0 20px 0px rgba(0, 0, 0, 0.1);
}
.slide-left-leave-to {
    opacity: 0.4;
    transform: translateX(-50%);
}
  • 動(dòng)畫設(shè)置完成了,接下來需要判斷動(dòng)畫觸發(fā)邏輯,前進(jìn)還是后退
    這里我采用了路由跳轉(zhuǎn)設(shè)置params.routeMode的方式來決定動(dòng)畫形式
const router = useRouter();

router.beforeEach((to, from) => {

    const toDepth = to.params.routeMode;

    if (toDepth === "push") {
        to.meta.transitionName = "slide-left";
    } else if (toDepth === "pop") {
        to.meta.transitionName = "slide-right";
    }
    return true;
});
  • 最后是模板,路由入口設(shè)置動(dòng)畫
<router-view v-slot="{ Component, route }">
    <transition :name="route.meta.transitionName">
        <component :is="Component" />
    </transition>
</router-view>

結(jié)果展示

vue過場動(dòng)畫效果

完整Demo地址:https://github.com/ZTStory/vue_page_transition
在線演示:https://ztstory.github.io/vue_page_transition/#/
ps:如何搭建自己GitHub Pages?看這里

歡迎大家互相學(xué)習(xí),喜歡別忘記star哦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,346評論 3 23
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,119評論 2 59
  • 轉(zhuǎn)載請聲明 原文鏈接 關(guān)注公眾號獲取更多資訊 這篇文章主要總結(jié)H5的一些新增的功能以及一些基礎(chǔ)歸納,這里只是一個(gè)提...
    前端進(jìn)階之旅閱讀 9,229評論 22 225
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,898評論 28 54
  • 人工智能是什么?什么是人工智能?人工智能是未來發(fā)展的必然趨勢嗎?以后人工智能技術(shù)真的能達(dá)到電影里機(jī)器人的智能水平嗎...
    ZLLZ閱讀 4,115評論 0 5

友情鏈接更多精彩內(nèi)容