Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
YIXUNFE opened this issue Feb 6, 2016 · 0 comments
Open

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

YIXUNFE opened this issue Feb 6, 2016 · 0 comments

Comments

@YIXUNFE
Copy link
Owner

YIXUNFE commented Feb 6, 2016

易豆每日签到功能实现

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

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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant