当前位置: 首页 > 科技观察

前端实战:利用CSS3实现在线直播之类的排队动画

时间:2023-03-13 22:43:00 科技观察

之前群里有朋友问过这样的问题,类似直播平台的用户在小程序上线时如何实现排队动画?作为前端工程师,解决方案无外乎以下两种:使用javascript根据条件控制元素的样式实现队列动画和使用纯css3配合数据驱动模型实现。大家都知道,在现代的web开发中,我们尽可能的使用Css来达到效果。使用Js,所以我们应该优先使用Css3来实现,但是我们需要结合数据流来实现真正的队列动画,所以我们可以使用MVVM框架方便的数据驱动模型来控制动画的方向。并且因为动画的核心在于css3,原理其实在小程序或者Vue/React中都是类似的,不用担心技术栈问题。下面是实现后的效果图:如果上面的gif无法访问,可以查看下面的静态图:其实这个效果用在很多地方,比如B站的弹幕,粉丝的直播动图一个音乐平台,以及某个音乐平台的动画。直播等,但是在Web端,如何实现呢?接下来笔者就带大家一步步实现这样的动画效果。要实现上面的动画效果,首先要对动画进行分析,如上图动画结构如下:动画分为以下两个过程:用户进入动画和用户淡出。还有一个细节就是不管有多少用户进入,都是从同一个位置进入的。这时候,之前用户的位置就会上移。如下图所示:所以实现这个效果最好的方法就是使用定位,比如绝对定位(absolute)或者固定定位(fixed)。并设置其bottom值,如下代码所示:.animateWrap{position:absolute;bottom:40%;left:12px;}以上位置信息仅供参考,具体值可根据自己更改需要。设置bottom的好处是一旦添加了容器的子元素,就会自动将之前的元素推到顶部。我们需要手动设置它的偏移值。实现入口动画,如果我们要实现上图中的用户入口动画,可以使用css3的过渡动画transition或者animation动画。由于场景使用方便,我们这里使用动画动画。首先我们来写dom结构:/>

女士小李在线
女士李老师在线
女士李在线上面代码表示创建了一个动画容器,添加了2个用户。这里我们定义关键动画如下:.animate{margin-bottom:10px;border-radius:20px;background-color:rgba(0,0,0,.3);animation:moveIn1.2s;}@keyframesmoveIn{0%{transform:translateX(calc(-100%-12px));}100%{transform:translateX(0);}}上面实现了元素向右移动的动画,但是此时的动画我们see同时出现。如果我们要把它应用到真实的场景中,那肯定是通过socket或者roundrobin获取到的异步数据,所以我们可以使用setInterval来模拟这个过程。还有一个细节就是我们在动画中只能完整展示2条用户数据,多余的数据会淡出隐藏,所以我们需要截取数据。代码如下:const[user,setUser]=useState>([])useEffect(()=>{letMAX_USER_COUNT=2;lettimer=setInterval(()=>{setUser(prev=>{prev.push(Date.now()+''))if(prev.length>MAX_USER_COUNT+1){prev.shift()return[...prev]}else{return[...prev]}})},2000)},[])变量MAX_USER_COUNT用于控制最大显示用户数,可根据实际需要更改。setUser中的逻辑是阻塞逻辑。当用户数超过指定的最大值时,header元素将被删除以上就完成了数据传输的过程。我们还需要处理的是用户的淡出逻辑和动画。我们来看看淡出动画:@keyframesmoveOut{0%{opacity:1;}100%{opacity:0;}}其实动画并不难。我们需要控制的是如何动态地将这个动画添加到head元素中。这时候我们最好的方案就是使用类名,即当满足淡出的条件时,我们需要给元素动态设置淡出的类名,条件如下:user.length>MAX_USER_COUNT&&i===0上面的条件是指当用户数超过最大显示用户数且元素是head元素时,那么我们只需要按照这个条件动态设置类名即可:{user.map((item,i)=>{return2&&i===0?styles.hidden:'')}key={item}>李小姐{item}在线})}css代码如下:hidden{opacity:0;animation:moveOut1.2s;}通过以上步骤,我们实现了一个完整的类似在线直播的队列动画。完整的动画css代码如下。有兴趣的朋友可以学习参考:animateWrap{position:absolute;bottom:40%;left:12px;.animate{margin-bottom:10px;border-radius:20px;background-color:rgba(0,0,0,.3);animation:moveIn1.2s;.tx{display:inline-block;width:36px;height:36px;border-radius:50%;overflow:hidden;vertical-align:middle;margin-right:10px;img{宽度:100%;高度:100%;object-fit:cover;}}span{margin-right:12px;line-height:36px;font-size:14px;color:#fff;}}.hidden{opacity:0;animation:moveOut1.2s;}@keyframesmoveIn{0%{transform:translateX(calc(-100%-12px));}100%{transform:translateX(0);}}@keyframesmoveOut{0%{opacity:1;}100%{opacity:0;}}}本文转载自微信公众号“趣话前端”,转载文章可通过以下二维码关注,转载请联系趣话前端公众号。