1.前言以前看微信视频号直播的时候,经常点右下角的赞。看着它的数字从一位数慢慢变成五位数,颇有气氛。尤其是长按的时候,还有手机的震动反馈,非常有感触。虽然我很好奇这些飘动似的运动效果是如何实现的,但并没有特别去研究。直到前段时间投入到腾讯课堂H5直播间的需求中,需要自己实现这样的效果,才开始摸索。先来看看最终效果:相比视频号的like运动效果,轨迹要复杂很多。可以看到,课堂直播间的点赞动画大致分为三个阶段:1.从头开始,在上升过程中放大到正常大小2.在上升过程中左右摇摆,并且摇摆幅度是随机的3.在上下摇摆的过程中,在做之前先淡出收缩,我首先想到的是用CSS动画来实现这种运动轨迹。完成后用Canvas重构了一个版本来优化性能。接下来,我们分别来看一下这两种实现方式。2.CSS实现like运动效果2.1轨迹分析由于like动画是在二维平面上,我们可以将它的运动轨迹分成x轴和y轴两段。在y轴上很简单,我们的点赞图标会做一个匀速垂直向上的运动,从容器底部上升到容器顶部。x轴左右摇摆。从数学的角度来看,它是一种简谐运动。但是用css实现的话,就不需要那么精细了。为了简化计算,我们可以使用几个关键帧来串联这个运动轨迹,例如:@keyframesbubble_swing{0%{Middle}25%{Leftmost}75%{Rightmost}100%{Middle}}2.2轨迹设计根据针对以上分析,我们可以设计一段相同的上升轨迹,和几段不同的左右摇摆轨迹。上升轨迹很简单,我们还可以添加不透明度和变换变化,如下:@keyframesbubble_y{0%{transform:scale(1);保证金底部:0;不透明度:0;}5%{变换:缩放(1.5);不透明度:1;}80%{变换:比例(1);不透明度:1;}100%{底部边距:var(--cntHeight);变换:比例(0.8);不透明度:0;}}其中--cntHeight指的是容器的高度。也就是说,我们通过不断增加margin-bottom来控制点赞图标从容器底部上升到容器顶部。对于横向运动的轨迹,为了增加运动轨迹的多样性,我们可以设计多个摇摆轨迹,例如“中间->最左->中间->最右”的轨迹:@keyframesbubble_swing_1{0%{//中间margin-left:0;}25%{//最左边margin-left:-12px;}75%{//最右边margin-left:12px;}100%{左边距:0;}}这里也用margin来控制图标的左右移动。同样,我们也可以设计其他几个轨道://Anytrack@keyframesbubble_swing_2{0%{//Middlemargin-left:0;}33%{//最左边的margin-left:-12px;}100%{//随机位置margin-left:6px;}}//谐波反转@keyframesbubble_swing_3{0%{//middlemargin-left:0;}25%{//最右边margin-left:12px;}75%{//最左边margin-left:-12px;}100%{左边距:0;}}接下来我们结合x轴和y轴轨迹(@keyframes)并设置随机动画时间,例如:@for$ifrom1through3{@for$jfrom1through2{.bl_#{$i}_#{$j}{animation:bubble_ycalc(1.5s+$j*0.5s)linear1forwards,bubble_swing_#{$i}calc(1.5s+$j*0.5s)linear1forwards;}}}这里生成了3*2=6个不同的轨迹。对于这种重复的选择器,在SCSS中使用循环语法可以节省大量代码。2.3随机选择图片(Sprite图片)每次我们喜欢都会出现不同的icon,所以这里我们针对不同的icon设计了一系列的selector,让它们显示不同的图片。首先我们需要准备一张sprite图片,让所有的图标大小保持一致,然后使用SCSS循环语法:@for$ifrom0through7{.b#{$i}{background:url('../../images/like_sprites.png')计算(#{$i}*-24px)0;}}如上生成了8个选择器,我们可以在程序执行的时候随机给图标分配一个选择器。2.4生成点赞图标的CSS部分已经差不多完成了,下面看看JS是如何执行的。我们需要有一个容器div来保存要生成的类似图标。以及绑定点击事件的按钮:constcacheRef=useRef
