兔年创意:10.掉落元宝-3

121 阅读3分钟

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

介绍

马上就要过新年啦,原本我还不知道新的一年是什么年,到网上一查,原来新的一年是十二生肖中的-兔年。在这新春之际,掘金推出了兔了个兔-创意投稿大赛。上次参加掘金的活动,好像是几个月以前了,参加的是掘金的征文活动。参加完之后,工作上面有点忙,导致自己好久没有参加掘金的活动了。

现在掘金推出了兔了个兔-创意投稿大赛,现在自己的工作不是很忙,刚好有时间可以参加这个活动了。

该活动要求围绕“兔”这个元素展开创意,接下来马上就要开始创意了。

前言

在上一篇文章里兔年创意:9.掉落元宝-2里,我们已经把元宝掉落的效果做好了。

做完元宝掉落的效果后,我又有了新的想法。现在掉落元宝的数量是固定的,那我是否可以控制掉落元宝的数量呢?

答案是可以的,接下来我们就来实现一下控制元宝掉落的数量。

实现

分析

在上一篇文章里,我们已经实现了元宝掉落的效果。在这个基础上,我们想要增加一些其它效果,比如可以控制元宝掉落数量。怎么实现?

现在我是使用setInterval来不断地创建img标签,来展示很多的元宝。如果想要实现控制元宝的数量,那可以从setInterval来入手。

setInterval是javascript的内置函数,可以传递两个参数:

  • 参数一:要执行的回调函数
  • 参数二:时间间隔

我们可以使用第二个参数,时间间隔来实现。

当时间间隔越小时,就越快创建元宝,元宝的数量也就越多。

当时间间隔越大,就越慢创建元宝,元宝的数量也就变少了。

代码

上面已经分析完实现逻辑了,接下来就要写代码了。

html
<div class="wrap">
            <img class="rabbit" src="./image/rabbit1.png" alt="" />
</div>
<div>
            <button class="add">增加</button>
            <button class="sub">减少</button>
</div>

我在元宝下方,增加了两个按钮,分别用来控制增加或者减少。

let wrap = document.querySelector(".wrap")
        let addBtn = document.querySelector(".add")
        let subBtn = document.querySelector(".sub")
        let stopFn = null
        let step = 50
        let startTime = 300const imgList = [
            "./image/yuanbao1.png",
            "./image/yuanbao2.png",
            "./image/yuanbao3.png",
        ]
​
        function getRandomNumber(max) {
            return Math.floor(Math.random() * max)
        }
​
        function getRandomYuanbao() {
            let index = getRandomNumber(3)
            return index
        }
​
        function getRandomSize() {
            let index = getRandomNumber(40)
            if (index < 20) index = 20
            return index + "px"
        }
​
        function getLeft() {
            return getRandomNumber(330) + "px"
        }
​
        function createImg() {
            let img = document.createElement("img")
            img.className = "yuanbao"
            img.style.width = getRandomSize()
            let index = getRandomYuanbao()
            img.src = imgList[index]
            img.style.left = getLeft()
            img.style.top = "-70px"
            document.body.appendChild(img)
            //   observe(img);
            img.addEventListener("transitionend", (e) => {
                e.target.parentNode.removeChild(e.target)
            })
            setTimeout(() => {
                img.style.top = "360px"
            }, 500)
        }
​
​
    function start(time) {
            let timerId = setInterval(() => {
                createImg()
            }, time)
​
            function stop() {
                clearInterval(timerId)
            }
​
            return stop
        }
​
        stopFn = start(300)
​
        addBtn.addEventListener("click", function () {
            stopFn()
            startTime -= step
            stopFn = start(startTime)
        })
        subBtn.addEventListener("click", function () {
            stopFn()
            startTime += step
            stopFn = start(startTime)
        })

在原来的js代码基础上,再多增加了一些代码。

  • 我把整个动画的启动,封装成了一个start函数,调用start函数,就可以开始元宝掉落的动画了

  • 在start函数里,我又定义了一个stop函数。在stop函数里,是停止计时器。然后把stop函数返回

    为什么要返回stop函数?

    我是参考了vue里面的$watch的做法的,如果你使用过vue2,你就会知道,我们可以调用$watch来监听某个变量。调用$watch后,会返回一个函数,调用这个函数,就可以停止监听了。

    我主要是参考了$watch来做的,调用start函数,开启动画,返回stop函数。调用stop函数,就可以停止动画

  • 给增加按钮和减少按钮,监听点击事件,分别处理元宝增加或者减少的逻辑

运行index.html到浏览器,操作后可以看到元宝增加或者减少的效果。

增加效果:

add.gif

减少效果

sub.gif

小结

本小节,主要是实现了控制元宝掉落时的数量。主要思路是利用setInterval的第二个参数,通过控制它增加或者减少,来实现控制元宝数量的增加或者减少。

代码逻辑不是特别复杂,大家如果感兴趣,也可以自己实现一下。

最后,兔年来到,福兔祝你鸿福齐天,万事如意!