阅读 891

小程序轻量级点赞动画,基于CSS背景图实现

问题由来

打卡鸭小程序中的点赞动画效果

优点

礼花造型的动画,其动画效果是随机产生的。据UI设计师的话来讲,就是可以促进用户多多点赞。

存在的问题

现象:在小程序的打卡列表中,点赞50次以上后,可能就无法继续点赞了。

我猜的原因为创建了50以上的画布Canvas,每个画布都加载10个图片,导致小程序性能不足,出现卡住。

完整源码

完整源码,请在小溪里博客本文链接(点击参看原文)中查看 SoureMap 来获得。

小程序礼花型点赞动画的说明:基于小程序的Canvas的 ctx.draw() 来实现的,得益于 Taro H5 有相应的 draw 的代码才得以展现。

部分源码如下

const ctx = Taro.createCanvasContext('like-animation')

let _rw = canvasWidth / 300
let _rh = canvasHeight / 150

likeTimer = setInterval(() => {

  likeList = likeList.filter(_l => _l.d >= -30).map(_l => {
    _l = nextXY(_l)
    if (_l.d <= 0) {
      ctx.save()
      ctx.scale(_rw, _rh)
      ctx.beginPath()
      if (-_l.d > 20) {
        let _ga = (_l.d + 30) / 10
        ctx.globalAlpha = _ga > 0.2 ? _ga : 0
      }
      ctx.drawImage(_l.img, _l.x, _l.y, 18, 18)
      ctx.fill()
      ctx.restore()
    }
    return _l
  })

  if (likeList.length === 0) {
    clear(options)
  }

  ctx.draw()
}, 30)

// 计算图片位置
function nextXY({ a, x, y, h, k, s, d, img }) {
  if (d <= 0) {
    x = x + s
    y = (a * Math.pow(x - h, 2)) + k
  }
  d = d - 3
  return { a, x, y, h, k, s, d, img }
}
复制代码

业界优秀文章

行业方案

直播间动画

在掘金上搜到点赞动画,大部分为直播间动画,实现原理为Canvas上绘制图片,当然也有使用CSS动画的。具体可以参考《H5 直播的疯狂点赞动画是如何实现的?(附完整源码)》。

  • 使用 CSS3 Animation,需要创建更多动画元素,加入不同的动画延迟。
  • 使用 Canvas,需要创建画布,并加载多个图形资源,适合单个场景下使用(如直播间)

推特动画

在 Medium 上搜到《How Did They Do That? The Twitter “Like” Animation.》是基于雪碧图来完成的。

  • 好处为,单个元素即可完成。
  • 难点为:雪碧图中动画细节多,多为设计师定义,开发无法自己配置细节,如动画延迟时间和执行时间

而在 CodePen 搜到的动画多为 SVG 实现的,效果都是非常不错的。但是在小程序内是没法直接用 SVG 做动画的,仅能用来当做背景图来展示。

点赞动画思路

点赞动画首先感谢"XboxYan" 《CSS实现一个粒子动效的按钮》。我借鉴了其多个圆形渐变,改变其图片的background-sizebackground-position的原理。

我实现的效果

圆形效果

  • 点赞图形为圆形
  • 点赞动画是通过改变 background-sizebackground-position 来完成的

.like-icon:before {
  background-size: 10px 10px, 20px 20px, 15px 15px, 20px 20px, 18px 18px, 10px 10px, 15px 15px, 10px 10px, 18px 18px, 15px 15px, 20px 20px, 18px 18px, 20px 20px, 15px 15px, 10px 10px, 20px 20px;
  background-position: 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%;
}
#checkbox:checked + label .like-icon:before {
  opacity: 1;
  background-size: 0px 0px;
  background-position: 5% 65%, 1% 44%, 8% 25%, 20% 12%, 40% 2%, 52% 0%, 65% 5%, 78% 15%, 95% 30%, 100% 55%, 8% 85%, 23% 100%, 42% 105%, 60% 99%, 75% 90%, 92% 84%;
  transition: opacity 0.25s, background-position .35s ease-in-out, background-size .5s ease-in-out;
}
复制代码

心形效果

  • 点赞图形从圆形改为心形
  • 动画图标加入了切换缩放效果,带有一点弹性

/* 心形 */
#checkbox:checked + label .like-icon:before {
  background-position: 5% 65%, 1% 44%, 8% 25%, 20% 12%, 40% 22%, 52% 40%, 65% 25%, 78% 15%, 95% 30%, 100% 55%, 8% 85%, 23% 100%, 42% 105%, 60% 99%, 75% 90%, 92% 84%;
}

/* 点赞图标弹性效果 */
.like-icon {
  background: url('/images/posts/like-css3-animation/like-blue.png'), url('/images/posts/like-css3-animation/like-gray.png');
  background-size: 0px, 18px;
}
#checkbox:checked + label .like-icon {
  background-size: 18px, 0;
  transform: scale(1.05);
  transition: background-size .4s ease-in-out, transform 0.5s cubic-bezier(.97,.01,.76,4);
}
复制代码

心形动画调优

在实际点赞动画的数字变化中,会出现“❤点赞→❤1”、“❤9→❤10”的情况。

  • 整体居左,动画效果很理想
  • 整体居中或居右,在文字处发生变化时,心形位置会发生变化,此时需要加入一些动画延迟

/* 心形 */
#checkbox:checked + label .like-icon:before {
  opacity: 1;
  background-size: 0px 0px;
  background-position: 5% 65%, 1% 44%, 8% 25%, 20% 12%, 40% 22%, 52% 40%, 65% 25%, 78% 15%, 95% 30%, 100% 55%, 8% 85%, 23% 100%, 42% 105%, 60% 99%, 75% 90%, 92% 84%;
  transition: opacity 0.25s, background-position .35s ease-in-out, background-size .5s ease-in-out;
  transition-delay: 0.2s;
}

/* 点赞图标弹性效果 */
.like-icon {
  background: url('/images/posts/like-css3-animation/like-blue.png'), url('/images/posts/like-css3-animation/like-gray.png');
  background-size: 0px, 18px;
}
#checkbox:checked + label .like-icon {
  background-size: 18px, 0;
  transform: scale(1.05);
  transition: background-size .4s ease-in-out, transform 0.5s cubic-bezier(.97,.01,.76,4);
  transition-delay: 0.2s;
}
复制代码

总结

直播间的动画,使用 CSS3 Animation 或 Canvas 效果会非常棒,只不过需要的动画元素更多。而我是想用 一到两个 DOM 元素配合 CSS 实现更轻量级的动画。

下一次可能的挑战

Josh 大神的点赞动画非常棒,我下一次也想挑战做一个类似的。

预览网址:Building a Modern-Day Hit Counter

致谢

  • 感谢李波、小顾同学之前实现的完整的点赞动画
  • 感谢帅帅、老吴提供的动画修改建议
  • 感谢我家小雪的鼎力支持
文章分类
前端
文章标签