• <menu id="gokgi"></menu>
    <nav id="gokgi"><nav id="gokgi"></nav></nav> <menu id="gokgi"><tt id="gokgi"></tt></menu>
    您的位置:首頁 >聚焦 >

    卡片放大播放效果實現總結,不同元素間的放大過渡效果如何實現? 世界速看料

    2023-01-09 20:43:30    來源:程序員客棧

    背景

    最近一段時間做了幾個需求,其中涉及的素材列表展示,需要實現類似下方圖片中的動效,暫且稱之為【卡片放大播放動效】,具體細節如下:

    初始展示的是封面圖片,鼠標經過時是視頻放大的效果;下方文字內容區域,在放大前后展示的內容不同,而且兩者的字體大小是一致的,不是簡單的放大實現;四五個頁面都需要實現相同列表效果,列表的行數和列數是不一致的;
    image
    遇到的四個問題

    在整個實現過程中,遇到以下四個問題,后面的解析中會有對應解答。


    【資料圖】

    不同元素間的放大過渡效果如何實現?抽離為通用性組件時,如何實現類vue中的具名插槽效果,來替換下方文字信息區域?不同頁面中的列表區域寬度不同,有的頁面列表還是彈性寬度,常用的flex布局無法滿足要求,如何實現呢?邊界卡片放大后,如何避免被父級列表容器overflow:hidden`隱藏掉?實現解析

    這個動效,在愛奇藝官網也有類似效果,愛奇藝官網是通過生成初始狀態卡片列表和鼠標放大卡片列表兩套列表,然后通過動態計算放大卡片位置,相對于body進行絕對定位展示的。

    本實現方案通過將卡片初始狀態和放大狀態,封裝到一個組件中,通過兩者間的相對關系,利用css自動完成對應關系,避免了大量的JS計算。

    1. 放大效果實現

    UI對該動效的要求實際就是鼠標視頻放大播放,如果卡片初始狀態也放置視頻video,通過transition對同一元素進行scale放大也可以實現,但是這是一個列表,用戶進入頁面,就會同時加載多個視頻,用戶體驗不是很好。

    所以,實現方案就是卡片初始狀態放置poster圖片,鼠標經過時,在poster上方展示視頻層(絕對定位),然后對視頻執行animation動畫來模擬放大效果。

    卡片底部文字區域如何處理?

    由于卡片初始狀態下,底部文字區域在列表布局中是占位的,所以在卡片初始狀態下,底部文字區域使用正常文檔流。

    卡片鼠標經過狀態下,視頻層的放大效果是以poster中心點為放大原點的,所以底部文字區域使用absolute定位,相對于player進行定位處理。

    interfaceIItemData{src?:string;poster?:string;industry?:string;}interfaceIProps{posterClass:string;//poster區域寬高playerClass:string;//放大后視頻寬高樣式itemData:IItemData;children:{[key:string]:any};}lett:NodeJS.Timeout;constVideoItem:FC=({posterClass,playerClass,itemData,children,})=>{const[isHover,setIsHover]=useState(false);constonMouseEnter=()=>{t=setTimeout(()=>{//避免快速移動鼠標,造成視頻無法隱藏問題setIsHover(true);},50);};constonMouseLeave=()=>{clearTimeout(t);setIsHover(false);};return(Top1
    {isHover?({children?.playerBottom}
    ):null}{children?.posterBottom});};exportdefaultVideoItem;

    .container{position:relative;.poster{position:relative;background-position:center;background-size:cover;background-repeat:no-repeat;.player{z-index:10;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)scale(0.929);animation:showPlayer0.2sease;animation-fill-mode:forwards;.playerBottom{width:100%;position:absolute;top:100%;left:0;box-shadow:0px6px16px-8pxrgba(0,0,0,0.08),0px12px48px16pxrgba(0,0,0,0.03);filter:drop-shadow(0px9px28pxrgba(0,0,0,0.05));}}}.posterBottom{width:100%;}}@keyframesshowPlayer{0%{transform:translate(-50%,-50%)scale(0.929);}100%{transform:translate(-50%,-50%)scale(1);}}

    2. 抽離為通用組件時,卡片底部文字區域如何動態替換

    整個卡片組件,底部的文字區域在不同的場景下可能是不同的,所以作為通用性組件,需要將這部分抽離,支持動態替換。

    vue中最簡單的方式,就是插槽,通過插槽從外部動態傳入。但是react框架是不支持具名插槽的。所以,這個問題就轉換成了,react如何實現具名插槽?

    網上搜到了一種實現方式,通過傳入一個object來實現,具體效果如下:

    //cardList{{posterBottom:bottomInfo,playerBottom:bottomInfo,onClickPlayer:()=>{consturl=`${window.location.origin}/#/market/service/${item.itemId}`;window.open(url,"_blank");},}}//VideoItem{props.children?.playerBottom}{props.children?.posterBottom}

    當然,具名插槽還有其它的實現方式,后面會專門寫一篇文章總結學習下。

    3. 列表容器如果是彈性布局時,每行的列數無法固定,flex布局無法滿足

    這個問題是一個通用性問題,在容器寬度不固定時,flex布局,每行最后一個元素無法選中設置樣式,同時子元素個數不固定時,最后一行元素的間距會變大。

    這種情況下,就需要grid布局大顯身手了,以前很少用grid布局,這次也是學習到了,具體效果如下圖:

    在示例中,調整瀏覽器窗口大小,來實驗彈性布局觀看效果代碼片段

    image.png
    4. 卡片放大后,可能會被容器設置的overflow:hidden給遮蓋隱藏掉

    目前放大效果的實現方式,放大的視頻層是絕對定位的,參照物是每個卡片本身。所以在四周邊界處的卡片,放大后,很容易被容器給遮蓋。

    處理方式也很簡單,給容器多設置一些padding,讓放大部分足夠展示,然后用margin設置負值來調整布局

    .container{margin-left:-20px;margin-right:-20px;padding-left:20px;padding-right:20px;}

    總結

    每個產品需求里,可能都會隱藏著自己的盲點,將效果做到極致,就能獲得技術成長。在重復的需求里,多反思總結,尋找自己的提升點,這就是進步吧啊。

    相關推薦

    1.CSS 實現按鈕點擊動效的套路

    2.年份數字拼圖效果

    3.跑馬燈簡單版

    4.中心點靠近動畫解析

    關鍵詞: 初始狀態 絕對定位 這個問題

    相關閱讀

    和老少妇做真爽
  • <menu id="gokgi"></menu>
    <nav id="gokgi"><nav id="gokgi"></nav></nav> <menu id="gokgi"><tt id="gokgi"></tt></menu>