YIXUNFE / blog

文章区
151 stars 25 forks source link

易豆每日签到功能实现 #55

Open YIXUNFE opened 8 years ago

YIXUNFE commented 8 years ago

易豆每日签到功能实现

为了更好的推动电商媒体化战略,产品希望在网站的顶部增加“每日签到”功能,每天签到可以赠送易豆(类似于积分的概念,目前仅用于报名众测活动,原因是众测活动太火热了,用易豆做为门槛)。由于是偏向社交的功能,所以在交互方面的效果会更加注重一些。

目前初版已经完成(年后发布),效果图如下:

1

下面就来说说签到功能中一些效果的实现。


数字动画

从效果图中可以看到,当获取到用户的易豆数量以及签到成功后增加易豆的时候,易豆数量都会有一个不断变化数字的动画效果。实现这个效果的方法如下:

/**
 * 数字变换动画
 * @param {Number|String} oldNumber 初始值
 * @param {Number|String} deltaNumber 增量
 * @param {Number} time 动画时长
 */
function _aniNumber (oldNumber, deltaNumber, time) {    
  var unitTime = 0, deltaNumber = parseInt(deltaNumber, 10), obj = dom.find('.sign_count'), oldNumber = parseInt(oldNumber, 10), current = oldNumber, unit = 1

  if (deltaNumber === 0) {return}

  unit = Math.ceil(deltaNumber / 100)
  unitTime = time / deltaNumber * unit

  function change (num) {
    current += unit
    obj.html(num)
    setTimeout(function () {
      if (current <= oldNumber + deltaNumber) {
        change(current)
      } else {
        obj.html(oldNumber + deltaNumber)
      }
    }, unitTime)
  }

  change(current)
}

实现的原理是获取单次数值变化的时间间隔,然后利用 setTimeout 函数重复的设置 DOM 中的数字。需要注意的是,为了在处理相当大的增量(比如 deltaNumber 是 10000 时)的时候不出现动画需要很久才结束的问题,需要对求单次数值变化时间间隔的方式上做一些技巧。

从实际需求考虑,数字动画有如下特点:

为了满足这两个特点,我们将单次的变化量最小设置为增量的 1%,那么动画的执行次数最多是 100 次,虽然这时候的动画时间 time 可能受到 setTimeout 方法的最小执行间隔的影响(基本在 15 毫秒内,这个数值受浏览器与操作系统影响),那么最差的情况下执行 100 次,15 毫秒一次,完成动画就需要 1.5 秒,时间上还是可以接受的,只是这是的时间设置在 1500 以内时并没有多大意义了。

另外这里并没有使用 requestAnimationFrame 方法,主要是考虑到是一个小功能点,没必要写大段的兼容代码。


签到成功后的动画

在当日签到成功后,会出现一个提示动画,动画的效果是上升,并放大和渐隐。

放大效果不能使用拉伸图片的方式,而要使用 CSS3 的 transform 样式,主要是因为动画元素中有一个 +20 的文案,这文案里面的数值是和签到的数据相关的,无法做成图片。

考虑到 transitiontransform 在 IE 下支持不好,所以将整个动画拆成了两部分,一部分是 JS 控制的,可以兼容 IE,另一部分以 CSS3 为主,做放大效果。

dom.find('.sign_ani').animate({
  opacity: 0,
  top: -20
}, 300, function () {
  $(this).remove()
})
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
transform-origin: 50% 100%;
-webkit-transform: scale(1.5);
-moz-transform: scale(1.5);
transform: scale(1.5);

IE 下将只看到上升和渐隐效果,而 FF、Chrome 等可以看到更加亮眼的放大效果。


延迟加载

由于签到功能放在了整站的头部,而获取用户的签到信息、易豆数等接口请求频繁,会造成服务器不必要的压力。所以对接口的请求不应该自然发起,而是放在一个用户的操作中。这里设置在用户鼠标滑动至顶部“每日签到”标签后再请求。


Thanks