前言
人生天地之间,若白驹过隙,忽然而已。不知不觉中,2022年已然逝去,2023年也过去了半个月了。看到「兔了个兔」这个活动几天了,不过这周比较忙,没时间参与。
心血来潮,捣鼓了一晚上,实现一个兔年的红包雨(兔子雨)效果~ ??
展示效果
技术栈
- Vue2
- SCSS:实现红包雨(兔子雨)效果、按钮交互效果等。
思考与实现
首先,思考一下最终的展示效果:在屏幕上会有很多随机下落的兔子(红包),点击兔子弹出一个详情弹窗,会获得一定的现金或实物奖励。当然,获得的红包可能是一定金额,也可能是“谢谢参与”或者其他。类似的有支付宝的集五福活动、蚂蚁森林等场景。
接着,考虑如何实现这个场景。
红包下落效果
我们先设计一个简单的红包效果:

这里对于红包,使用的是绝对定位,并使用background属性设置渐变色。
- <div class="bag"></div>
- .bag{
- width: 30px;
- height: 50px;
- background: linear-gradient(to bottom, #ff6a00, #ee0979);
- position: absolute;
- top: 0;
- left: 0;
- user-select: none;
- cursor: pointer;
- }
为了实现下落效果,我们可以使用定时器不断增加top属性的值,直到超出屏幕为止。然而,当红包数量越来越多时,我们需要操作的DOM元素太多了,而且每个红包都加上一个定时器,并不优雅!!
思考了很久,后来想到可以借助CSS动画去实现!也就是,初始位置的top值是0,动画结束时是100vh,也就是红包移出屏幕的时候。借助CSS3 animation-fill-mode 属性,这里取值是:animation-fill-mode:forwards;
。最终红包刚好停留在屏幕下方那里(视野不可见)。
- .bag{
- animation: downBags 3s forwards linear;
- }
- // 红包的下落动画
- @keyframes downBags {
- 0% {
- top: 0;
- }
- 100% {
- top: 100vh;
- }
- }
生成红包雨
这里借助Vue2
来渲染和操作DOM。红包雨使用bags
变量来维护。交互开始时,触发 init 函数,每间隔 500ms 生成一个红包。当超出规定的数量(bagsNum,这里设置为20)后,停止生成红包。
Vue是操作DOM的利器!这里我们不需要手动创建DOM元素:var el = document.createElement('div');
然后再添加CSS样式。我们通过操作bags
数组,每生成一个红包就添加一个元素,并设置该元素对应的属性,比如top, left, money等等即可。是不是简单了许多?
- init() {
- let count = 0
- let countT = setInterval(() => {
- if (count >= this.bagsNum) {
- clearInterval(countT)
- this.gameover = true
- return
- }
- this.createBag(count)
- count++
- }, 500);
- },
- createBag(i) {
- let ran = Math.random()
- let money = Math.floor(ran * 1001)
- let desc = ''
- if (ran > this.prizeRatio) {
- money = 0
- desc = '谢谢参与!'
- }
- let deg = 0
- if (this.isRabbitBG) {
- deg = Math.floor(ran * 30)
- if (ran > 0.5) {
- deg *= -1
- }
- }
- let param = {
- index: i,
- money,
- desc,
- from: '掘金',
- top: 0,
- left: `${Math.floor(Math.random() * this.maxW)}vw`,
- deg,
- show: true,
- }
- this.bags.push(param)
- },
到这里,简单的红包雨效果实现了。

打开红包效果
样式和交互比较简单,点击按钮后,我们给按钮添加rotate样式,借助CSS动画去实现交互效果。这里就不赘述了。
- .rotate{
- animation: rotateAni linear .3s infinite;
- }
- @keyframes rotateAni {
- from{
- transform:rotateY(180deg);
- }
- to{
- transform:rotateY(360deg);
- }
- }

兔子雨效果
兔年到了,当然要尝试下“兔子雨”了... 这里我们把红包换成兔子,为了使得“兔子雨”效果看上去更优雅一些,我们给兔子图片随机设置了一定的旋转角度(±30°之间)。
- .bagRabbitBG{
- width: 70px;
- background: url(https://clemmensen.top/static/rabbit1.png) center / cover no-repeat;
- }
- createBag(i) {
- let ran = Math.random()
- // ...
- let deg = 0
- if (this.isRabbitBG) {
- deg = Math.floor(ran * 30)
- if (ran > 0.5) {
- deg *= -1
- }
- }
- // ...
- }
实际效果如下:

拓展
设置中奖概率
这里我们可以设置中奖概率为75%。当随机数大于0.75时,中奖金额市值为0,文案设置为"谢谢参与!"。
- createBag(i) {
- let ran = Math.random()
- let money = Math.floor(ran * 1001)
- let desc = ''
- if (ran > this.prizeRatio) {
- money = 0
- desc = '谢谢参与!'
- }
- // ...
- }
后记
这几天一直比较忙,趁着今天有空一些,参与了这个「兔了个兔」活动。
总的来说,从 idea 的产生到动手实现“兔子雨”的过程还是挺有意思的!在这里,预祝各位掘友兔年快乐,前兔似锦!
以上就是JS技巧动手实现红包兔子雨效果示例详解的详细内容,更多关于JS 实现红包兔子雨效果的资料请关注w3xue其它相关文章!