本文介绍一个lao虎机抽奖动画的实现,lao虎机抽奖在各类商家营销活动中非常常见,这里主要介绍动画的实现过程,其他细节不做详细分析。

ps:lao虎机是敏感词,博客园的富文本和markdown编辑器都限制不允许出现,所有老用拼音。

1. 需求

尔珍小说网 https://www.juei.info

UI给到的蓝湖如下截图1

图1

  • 三栏图片,每栏图片是一样的,都包含所有的奖品图片。
  • 点击抽奖三栏图片从左到右依次开始上下滚动,从慢到块,滚动几轮后根据抽奖结果固定图片位置。
  • 如果中奖三栏显示同一张奖品图片,否则随机显示三张奖品图片。最后弹出抽奖结果弹框。

2. 整体思路

2.1 滚动

说到滚动,首先想到的是scroll,但是scroll会有滚动条出现。并且需求要求先滚动几轮,这个使用scroll的话我暂时想不出什么好的办法。
然后想到可以使用background-img结合background-repeat,background-position-y来实现这个功能,简单说就不断地修改背景图片的background-position-y,并且设置背景重复显示,这样看起来就是奖品图片在滚动了。

2.2 jquery动画

虽然可以使用css中的animation动画来让背景滚动,但是这里有个问题,在开始滚动图片同要去请求接口,在接口有了结果之后要根据结果来固定图片位置,使用keyframe的话要动态设置关键帧,这也很麻烦。
其实jquery提供了响应的api来修改元素的尺寸信息,和尺寸相关的都可以使用jquery动画。参考jquery文档如下:

所有用于动画的属性必须是数字的,除非另有说明;这些属性如果不是数字的将不能使用基本的jQuery功能。(例如,width, height或者left可以执行动画,但是background-color不能,除非使用jQuery.Color()插件。)属性值的单位像素(px),除非另有说明。单位em 和 %需要指定使用。

另外,背景开始滚动的时候是空转的,然后等到有抽奖结果之后在原来的background-position-y的基础上加上一个值,意思再滚动一个距离,固定在奖品图片上。这个需求和jquery动画属性中“相对值”的概念不谋而合。参考下面的jquery引文。

动画属性也可以是一个相对值。如果提供一个以+= 或 -=开始的值,那么目标值就是以这个属性的当前值加上或者减去给定的数字来计算的。

等待接口有响应之后还要播放第二个动画固定奖品,这时就要再播放一个动画,jquery已经想到了这个问题,所有提供一个done回调方法,如下:

done
Type: Function( Promise animation, Boolean jumpedToEnd )
在动画完成时执行的函数。 (他的Promise对象状态已完成). (version added: 1.8)..

2.3 尺寸问题

这个动画中尺寸问题至关重要,因为要对准奖品图片,尺寸稍有差别,就不容易设置好位置。还有UI给到我们的需求一般都是px,我们的vue项目中使用到“postcss-plugin-px2rem”插件会将px修改成相对的尺寸单位rem。postcss-plugin-px2rem配置如下:

'postcss-plugin-px2rem': {rootValue: 75,unitPrecision: 8,propWhiteList: [],propBlackList: [],selectorBlackList: [],ignoreIdentifier: false,replace: true,mediaQuery: false,minPixelValue: 3,exclude: /vant/i
}

这里最关键的信息是rootValue,设计稿给到的屏幕宽度是750px,这个值被换算成rem是750px/75=10rem,我们代码中所有的尺寸都会按照这个公式换算成rem。
然后我们动画中计算background-position-y的时候也要像这样换算一下,不然也有可能对不准奖品图片。

还有每个奖品图片在整张背景图中的次序也要先弄清楚,这里记在一个数组中,最后固定奖品图片的时候用到。如下:

prizeList: [{pid: 3251, order: 4, code: "HW-AM115", title: "华为半入耳式耳机AM115"},{pid: 3231, order: 3, code: "iphone-12", title: "苹果12 64G绿色"},{pid: 3261, order: 2, code: "PMC_iphone12_bhk", title: "浦诺菲-苹果12水晶保护壳"},{pid: 3271, order: 6, code: "PMC-18C", title: "浦诺菲_PMC-18C PD双口充电器"},{pid: 3241, order: 5, code: "SLY_RPB-N16", title: "丝兰雅_RPB-N16移动电源"},{pid: 3221, code: "lost", title: "离大奖就差一点点啦~"}
]

3.实现过程

3.1 布局

这里页面布局的时候要和UI沟通一个细节,就是背景图中上下两个奖品的间隔是最上面一个奖品和顶部中间间隔的两倍。如下图2

图2
同理,背景图中上下两个奖品的间隔是最下面一个奖品和底部中间间隔的两倍。如下图3

图3
最后整张背景图片如下图4

图4
这样滚动起来看上去是一张整体的图片,而不会出现偏差。三栏布局使用flex来实现,html代码如下:

<div class="session"><div class="lottory-box"><div class="top-fill"></div><div class="tiger tiger-first"></div><div class="tiger tiger-second center"></div><div class="tiger tiger-thired"></div><div class="bottom-fill"></div></div><img src="../assets/images/btn-lottery/btn-draw-lottery.gif" alt="" class="dray-lottery" @click="lotteryClick">
</div>

css代码如下:

.box {background: #FFBA76;width: 702px;margin: 50px auto;border-radius: 0px 0px 8px 8px;.session {padding-top: 22px;.lottory-box {position: relative;width: 664px;height: 341px;margin: 0 auto;background: no-repeat url("../assets/images/bg-lottery-box.png") center/664px 341px;border-radius: 8px;@include flex(center, center, nowrap, row);.tiger-first, .tiger-second, .tiger-thired {width: 191px;height: 341px;}//背景图是同一个图片,y轴位置不同.tiger-first {background: url("../assets/images/img-prizelist-border.png") center 62px/191px auto;}.tiger-second {background: url("../assets/images/img-prizelist-border.png") center -167px/191px auto;}.tiger-thired {background: url("../assets/images/img-prizelist-border.png") center -396px/191px auto;}.center {margin: 0 20px;}.top-fill, .bottom-fill {position: absolute;}.top-fill {top: 0;width: 660px;height: 49px;background: linear-gradient(180deg, #D15000 0%, rgba(241, 92, 0, 0) 100%);border-radius: 5px 5px 1px 1px;}.bottom-fill {bottom: 0;width: 660px;height: 49px;background: linear-gradient(180deg, rgba(241, 92, 0, 0) 0%, #D15000 100%);border-radius: 1px 1px 7px 7px;}}img.dray-lottery {width: 549px;}}
}

注意初始状态下,tiger-first,tiger-second,tiger-thired三张背景图片的定位已近写在css里面,可以根据情况调整。最后界面效果如下图5:

图5

3.2 动画

布局有了就可以让它动起来了,首先让三张背景图匀速运动起来,最后一起停止。代码如下:

lotteryClick() {let u = 1145                             //整个背景高度let that = this//播放动画jQuery(".tiger").each(function(index) {let currNum = jQuery(this)currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},{easing: "easeInOutCirc", duration: 4000 })})
}

变量u是整个背景图片的高度,先让背景滚动3次,然后再除以75得到先对单位rem,这个75就是上面提到的rootValue,这里用到的是'+=',也就是在原有的backgroundPositionY的基础上再加上一个相对的位移,duration:4000,让这个动画整个执行4秒钟时间。效果如下图6

图6

需求要求三张图片从左到有先后滚动,这个可以使用setTimeout(fn, time);来实现,代码如下:

//播放动画
jQuery(".tiger").each(function(index) {let currNum = jQuery(this)setTimeout(() => {currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},{easing: "easeInOutCirc", duration: 4000 })}, index * 300)
})

利用jquery中each的参数index,代表当前元素的下标,乘以300,这样第一个立即执行,第二个300毫秒后执行,第三个600毫秒后执行,效果如下图7:

图6

为了使效果看起来更加逼真,可以让每个图片滚动的时间有所差异,第一个最短,最后一个最长,这样看起来效果更逼真。方法是给一个延迟参数wast,加在配置参数duration上,代码如下:

lotteryClick() {let u = 1145                             //整个背景高度let waste = 800                          //调整动画时间//播放动画jQuery(".tiger").each(function(index) {let currNum = jQuery(this)setTimeout(() => {currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},{easing: "easeInOutCirc", duration: 4000 + index * waste })}, index * 300)})
}

效果如下图7

图7

3.3 请求接口&再动画

动画有了,现在要开始从接口中拿数据来定位奖品了。请求接口和上面的动画一起执行,这里假定接口响应的时间一定是少于2 * 300 + 4000 + 2 * 800 = 6200ms,一般来说这个时间足够了,这段时间内动画空转。拿到结果后再播放第二个动画来固定奖品图片。代码如下:

//避免重复点击
let that = this
if (this.disabled) {return
}
this.disabled = true
//抽奖
that.pid = -1
coc2.drawLottery({actId: actId.lottery}).then(res => {// 临时抽奖// res = {"code": "0","data":{"pid":3221}}if (res.code == 0) {let data = res.datathis.pid = data.pid} else if (res.code == 102002) {this.pid = 3221} else if (res.code == 303) {//拉起登录pullLogin()} else {this.lotteryMsg = res.message}
})

这里用一个变量pid记住奖品id,然后播放第二个动画,这时jquery动画提供了一个done方法执行动画完成之后的后续操作。代码如下:

//播放动画
jQuery(".tiger").each(function(index) {let currNum = jQuery(this)setTimeout(() => {currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},{easing: "easeInOutCirc", duration: 4000 + index * waste, done: function() {snapToGrid(currNum, index)}})}, index * 300)
})

snapToGrid方法就是执行第二个动画了,代码如下:

//对齐奖品图片
function snapToGrid(domObj, index) {let prizeNumber = 0//谢谢惠顾if ([3221, -1].includes(that.pid)) {let result = that.numRand()let numArr = (result + '').split('')prizeNumber = parseInt(numArr[index])} else {let prize = that.prizeList.find(p => p.pid == that.pid)prizeNumber = prize.order}domObj.animate({backgroundPositionY:  "+=" + (prizeH * prizeNumber) / 75 + "rem"},{easing: "linear", duration: prizeNumber * waste, done: function() {if (index == 2) {if (that.pid > -1) {that.$refs.dialogPrize.popUp(that.pid)} else {that.$toast(that.lotteryMsg)}that.disabled = false}}})
}

这里这里还有个逻辑,如果未中奖(谢谢惠顾),要生成三个不相等的随机数来让奖品图片固定,就是上面的that.numRand(),用它在0,1,2,3,4中随机选三个来固定奖品图片。具体方法如下:

//生成随机顺序
numRand() {let arr = ["0", "1", "2", "3", "4"], res = ""for (let i = 0; i < 3; i++) {let rnd = Math.floor(Math.random() * arr.length)res += arr[rnd]arr.splice(rnd, 1)}return res
}

还有个地方要注意,一开始的时候默认显示的奖品图片是没有对齐的,在动画空转3圈结束后让然不会对齐,等接口有结果后需要对齐奖品,而prizeList变量中纪录的order是按照从上到下的次序来的,最后固定到奖品图片时不可能对准。所以在开始动画之前要将每张背景图片固定到起始的位置,代码如下:

jQuery(".tiger").css('backgroundPositionY', 0)

最后看一下整体抽奖动画效果,如下图8

图8

4.总结

jquery动画提供了丰富的功能,能灵活的控制动画参数和想要的效果,在vue中虽然也提供了动画功能,但是处理一些复杂的操作用起来不是太理想。

抽奖动画 - lao虎机抽奖相关推荐

  1. 抽奖动画 - lao虎机抽奖,手把手教你做一个抽奖机软件

    本文介绍一个lao虎机抽奖动画的实现,lao虎机抽奖在各类商家营销活动中非常常见,这里主要介绍动画的实现过程,其他细节不做详细分析. 1. 需求 UI给到的蓝湖如下截图1 图1 三栏图片,每栏图片是一 ...

  2. 扭蛋机html源码,jQuery动画扭蛋机抽奖代码

    特效描述:jQuery动画 扭蛋机抽奖.jQuery动画扭蛋机抽奖代码 代码结构 1. 引入CSS 2. 引入JS 3. HTML代码 100/次 10000 > 恭喜你! 获得一等奖! 恭喜你 ...

  3. php幸运扭蛋机抽奖程序源码

    php幸运扭蛋机抽奖程序源码,可设置背景音乐,可设置中奖概率,可以设置奖项,可设置抽奖码指定中奖. 源码介绍 2种抽奖模式: 1.先登记资料,然后后抽奖, 2.匿名(无需登记,直接抽奖) 支持奖品数量 ...

  4. uniapp抽奖组件-动画效果之各类抽奖(跳跃)

    欢迎使用ay-lottery插件 最近对抽奖感兴趣,整理插件代码如下: 1.ay-lottery插件 可去uniapp插件市场的动画效果之各类抽奖(跳跃)页面下载. 前言 简介: 1.抽奖效果组件: ...

  5. 抽奖动画效果html,利用css实现一个抽奖动画效果

    首先我们先来看下最终的运行效果: 从效果图我们可以看到,抽奖会自动进行,并显示中奖信息. 这个效果基本是用CSS实现的,没有用图片,加一丢丢JS.完全没有考虑兼容性. 具体步骤如下: 首先画一个转盘 ...

  6. 第5章第13节:案例:制作一份企业年终抽奖动画 [PowerPoint精美幻灯片实战教程]

    很多公司都有年终抽奖的节目,您将在本节通过切换功能,实现抽奖动画的制作,由于需要使用多张幻灯片,所以先来创建一份母版. 点击幻灯片母版命令,进入幻灯片母版编辑界面. 使用键盘上的快捷键,全选版式中的所 ...

  7. Flutter 实现九宫格抽奖动画效果

    一.本文实现的九宫格抽奖动画效果如下 二.主要分享下怎么一步一步来实现这个效果 源代码地址 布局可以通过GridView轻松实现,只需在数据源的第五个位置插入一个元素用来标识是开始按钮 抽奖动画的实现 ...

  8. Js抽奖动画Demo

    抽奖动画效果如下图: 代码如下图: <style>.wrap {display: inline-grid;grid-template-columns: repeat(3, 33.3%);g ...

  9. html css年会照片抽奖,利用css实现一个抽奖动画效果

    首先我们先来看下最终的运行效果: 从效果图我们可以看到,抽奖会自动进行,并显示中奖信息. 这个效果基本是用CSS实现的,没有用图片,加一丢丢JS.完全没有考虑兼容性. 具体步骤如下: 首先画一个转盘 ...

最新文章

  1. IT职场人生系列之二十一:如何学习新语言(一)
  2. boost::allocate_unique相关的测试程序
  3. iOS 13 真机调试包
  4. 腾讯研发专家:TXSQL如何成为云计算时代数据库核弹头?
  5. idea git里的用户怎么修改
  6. C#发送Email邮件方法总结
  7. 读小米的《参与感》书的摘录(一),与大家分享!
  8. 【网络】HTTPS 怎么保证数据传输的安全性
  9. flink sql设置并行度_Flink原理——任务调度原理
  10. 抓取Js动态生成数据且以滚动页面方式分页的网页
  11. Android开发学习(3)Hello Android!
  12. 破解百度图片防爬虫机制(百度图片爬虫)
  13. 实验室家具系列之通风柜
  14. 【框架思路】python如何读取excel文件内容?如何获取excel文件的路径及sheet名称?
  15. [盘点]现今热门的h5网游
  16. 轻触开关的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 二分图(三)——KM算法
  18. easyswoole和mixphp_关于thinkphp5和swoole通过SMTP方式实现异步邮件群发的详解 - easyswoole...
  19. 关于企业微博运营的这10个技巧,有几个人知道?
  20. 地图数据设计(三):坐标参考系统的选择

热门文章

  1. 计算机科技文化节宣传标语,科技文化节宣传口号
  2. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十六)通用型角色头像面板...
  3. 天才基本法_关于天才基本法
  4. 怎样修复计算机系统声音,电脑没声音是怎么回事?小编教你怎么修复
  5. 谷歌浏览器的插件拦截
  6. 如何在30岁前年薪超过30万
  7. classpath类路径是什么
  8. linux命令之磁盘清理
  9. 计算机大赛鼓励语录,班级标语激励语录(精选50句)
  10. 51单片机c语言随机函数,[转载]51单片机中生成随机数