卡片放大播放效果實現總結,不同元素間的放大過渡效果如何實現? 世界速看料
背景
最近一段時間做了幾個需求,其中涉及的素材列表展示,需要實現類似下方圖片中的動效,暫且稱之為【卡片放大播放動效】,具體細節如下:
初始展示的是封面圖片,鼠標經過時是視頻放大的效果;下方文字內容區域,在放大前后展示的內容不同,而且兩者的字體大小是一致的,不是簡單的放大實現;四五個頁面都需要實現相同列表效果,列表的行數和列數是不一致的;在整個實現過程中,遇到以下四個問題,后面的解析中會有對應解答。
【資料圖】
這個動效,在愛奇藝官網也有類似效果,愛奇藝官網是通過生成初始狀態卡片列表和鼠標放大卡片列表兩套列表,然后通過動態計算放大卡片位置,相對于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