背景
最近一段时间做了几个需求,其中涉及的素材列表展示,需要实现类似下方图片中的动效,暂且称之为【卡片放大播放动效】,具体细节如下:
初始展示的是封面图片,鼠标经过时是视频放大的效果;下方文字内容区域,在放大前后展示的内容不同,而且两者的字体大小是一致的,不是简单的放大实现;四五个页面都需要实现相同列表效果,列表的行数和列数是不一致的;在整个实现过程中,遇到以下四个问题,后面的解析中会有对应解答。
【资料图】
这个动效,在爱奇艺官网也有类似效果,爱奇艺官网是通过生成初始状态卡片列表和鼠标放大卡片列表两套列表,然后通过动态计算放大卡片位置,相对于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
.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布局,这次也是学习到了,具体效果如下图:
在示例中,调整浏览器窗口大小,来实验弹性布局观看效果代码片段
目前放大效果的实现方式,放大的视频层是绝对定位的,参照物是每个卡片本身。所以在四周边界处的卡片,放大后,很容易被容器给遮盖。
处理方式也很简单,给容器多设置一些padding,让放大部分足够展示,然后用margin设置负值来调整布局
.container{margin-left:-20px;margin-right:-20px;padding-left:20px;padding-right:20px;}总结
每个产品需求里,可能都会隐藏着自己的盲点,将效果做到极致,就能获得技术成长。在重复的需求里,多反思总结,寻找自己的提升点,这就是进步吧啊。
相关推荐1.CSS 实现按钮点击动效的套路
2.年份数字拼图效果
3.跑马灯简单版
4.中心点靠近动画解析
背景最近一段时间做了几个需求,其中涉及的素材列表展示,需要实现...
为喜迎癸卯兔年到来,让全市人民度过一个欢乐、祥和、喜庆、文明的...
去年5月,随着苹果宣布最后一款iPod停产,也意味着这款发布距今21年...
《都挺好》自播出以来就深受大家喜爱,剧中苏明玉的二嫂被很多观众...
以下内容,均摘自于互联网,由于传播,利用此文所提供的信息而造成...
2023年01月11日公告发布
卫光生物:第三届董事会第十一次会议决议公告
网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征...
近日,多家券商预测2023年科技行业走势,集中表达看好数字安全市场...
网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征...
网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征...
近日,在青岛各个群中流传着一张截图,截图称“青医(现在的青大附...
兰姆和杰罗姆,勇士迫在眉睫且艰难的选择,科尔,勇士队,美国篮球,兰...
《梦华录》的成功让网友们掀起了童年回忆,“神仙姐姐”刘亦菲似乎...
维科技术(600152)01月09日在投资者关系平台上答复了投资者关心的问题。
1、产生罚息这是金钱上的损失。如果信用贷款出现逾期,贷款机构会先...
证券时报e公司讯,金刚光伏(300093)今日接受机构调研时表示,吴江1...
中国质量新闻网讯2023年1月5日,广东省市场监督管理局网站发布2022...
读创 深圳商报记者祁琦由搜狐视频出品、霍尔果斯视外谊海传媒有限...
智通财经APP讯,沃尔核材公告,公司拟分拆下属控股子公司乐庭电线工...
2023年1月5日江苏博云融资净偿还48 88万元,融资余额4752 46万元
2023珠海核酸检测时间不需要很久,几秒就做完!发热门诊急诊患者6小...
1月5日共享经济板块较上一交易日上涨1 82%,新日股份领涨。当日上...
凤凰网原创丨今年春节,返乡的人们还是少串门少聚集为宜:让人情与...
基本消息面周三(1月4日),在美联储公开市场委员会(FOMC)公布上次会...
中国青年网南昌1月4日电为进一步倡导绿色、低碳、环保生活方式,加...
期货一年9万到5000万,做期货真的能做到一夜暴富吗?
智通财经APP讯,微光股份发布公告,该公司全资子公司杭州微光技术有...
网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征...
按理说,如实的写自己过去的经历,没啥可怕的,但许多打工人对背调...