-
Notifications
You must be signed in to change notification settings - Fork 25
Description
易豆每日签到功能实现
为了更好的推动电商媒体化战略,产品希望在网站的顶部增加“每日签到”功能,每天签到可以赠送易豆(类似于积分的概念,目前仅用于报名众测活动,原因是众测活动太火热了,用易豆做为门槛)。由于是偏向社交的功能,所以在交互方面的效果会更加注重一些。
目前初版已经完成(年后发布),效果图如下:
下面就来说说签到功能中一些效果的实现。
## 数字动画
从效果图中可以看到,当获取到用户的易豆数量以及签到成功后增加易豆的时候,易豆数量都会有一个不断变化数字的动画效果。实现这个效果的方法如下:
/**
* 数字变换动画
* @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 的文案,这文案里面的数值是和签到的数据相关的,无法做成图片。
考虑到 transition 和 transform 在 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