js中运动函数的封装及应用

最近在学习js的过程中,学习了运动函数的封装。

在日常学习工作中经常需要设置一些运动效果,此时就需要用到运动函数,提前封装好一个运动函数可以在需要做其他的效果的时候进行引用,极大提高了重用率,大大增加我们的效率。

下面将分为三个步骤展示 :

一是运动 函数的封装,

二是编写一个小球运动效果,帮助对运动函数的理解,

最后编写一个稍复杂的烟花效果的页面,展示对封装的运动函数的应用。

首先,封装一个运动函数:

我们知道,运动三要素:谁运动(对象),属性,目标

emmm,算了,废话不多说,直接展示demo(思路逻辑都写在注释中,不再赘述)

        /*****封装一个运动函数*****/

        var times = '';

        function move(ele, target, way) {
            //事先清除一下定时器
            clearInterval(times);

            times = setInterval(function () {

                //先设置一个开关,定义初始值为true
                var onOff = true;

                //用for in 循环遍历运动的属性(方向、目标),即遍历(target)
                for (let attr in target) { //attr表示运动的属性

                    //获取元素运动到哪里了的实时值
                    //想要获取实时值,就要在外部封装一个获取实时位置的函数方法,然后再            
                      通过调用这个方法获取实时值并保存
                    let now = parseInt(getPos(ele, attr))

                    //计算此时速度的值(speed)
                    let speed = (target[attr] - now) / 10;

                    //取整数(向上向下取整)
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

                    //设置一个开关的状态(true)用来表示元素运动到终点
                    if (now == target[attr]) {
                        onOff = true;
                    }

                    //让元素运动
                    ele.style[attr] = now + speed + 'px';
                }

                //判断开关的状态,如果到达终点则停止定时器
                for (var tip in target) {
                    if (target[tip] !== parseInt(getPos(ele, tip))) {
                        onOff = false;
                        break;
                    }
                }

                if (onOff) {
                    clearInterval(times);
                    way && way();
                }

            }, 30)
        }

利用封装好的运动函数进行小球的运动效果(此处只展示小球运动的代码,不再重复上述的运动函数的代码)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 250px;
            height: 250px;
            background-color: gray;
            border-radius: 50%;
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>

<body>

    <div id="run"></div>

    <button id="btn">开始</button>

    <script>
        //获取节点
        let runObj = document.getElementById('run');
        let btnObj = document.getElementById('btn');

        //设置运动的目标值,(要运动到哪里)
        let target = 1000;

        //设置按钮点击事件
        btnObj.onclick = function () {
            move(runObj, {
                left: target
            }, function () { // 这里这个function是指元素运动到目标值之后要进行的操作的 
                                函数方法

            })
        }

        /*****此处加入已封装好的运动函数即可运行****/
    </script>
</body>

</html>

最后实现一个烟花效果

点击指定区域,会升起一个点(大烟花),然后随机到达一定高度便爆炸生成多个五颜六色(通过随机色实现)的小烟花

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #container {
            width: 80%;
            height: 600px;
            border: 1px red solid;
            position: relative;
            margin: 20px auto;
            cursor: pointer;
            background: black;
        }

        .fire {
            background: red;
            position: absolute;
            /* 设置bottom时,top获取为最大值,减去鼠标点击位置 */
            bottom: 0px;
            width: 6px;
            height: 6px;

        }

        .small-fire {
            width: 10px;
            height: 10px;
            position: absolute;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div id="container">

    </div>

    <script>
        //绑定节点,绑定点击事件
        let conObj = document.getElementById('container');
        conObj.onclick = function (eve) {
            //获取节点位置
            let pos = {
                cx: eve.offsetX,
                cy: eve.offsetY
            }
            //new构造一个Fire函数
            new Fire(conObj, pos);
        }

        /***大烟花的实现***/

        function Fire(conObj, pos) {
            //因为在后面也要用到,多次使用,所以先把属性设置成变量
            //此时的this指向对象(fire)
            this.pos = pos;
            this.conObj = conObj;
            // console.log(this);

            //生成烟花div,且追加class
            let bigDiv = document.createElement('div');
            //在bigDiv中追加一个类
            bigDiv.classList.add('fire');

            //设置大烟花样式
            bigDiv.style.left = pos.cx + 'px';
            bigDiv.style.background = this.getColor();
            // console.log(this);  //this指向当前节点对象(Fire)

            //追加到conObj中
            this.conObj.appendChild(bigDiv);

            //调用运动函数,从底部运动到鼠标点击的位置
            this.move(bigDiv, {
                top: this.pos.cy
            }, () => {
                bigDiv.remove();
                this.smallFire()
            })
        }

        /*******小烟花的实现*******/

        Fire.prototype.smallFire = function () {
            //随机生成小烟花个数
            let num = this.rand(20, 50);
            //循环,生成div
            for (let i = 0; i < num; i++) {
                let sFire = document.createElement('div');
                //添加class
                sFire.className = 'small-fire';
                //定义小烟花生成位置为鼠标点击的位置
                Object.assign(sFire.style, {
                    top: this.pos.cy + 'px',
                    left: this.pos.cx + 'px',
                    background: this.getColor()
                })
                //追加到页面中
                this.conObj.appendChild(sFire);
                //定义小烟花的top和left值,(随机生成的值),让它们四散开来
                let top = this.rand(0, this.conObj.offsetHeight - 
                    sFire.offsetHeight);
                let left = this.rand(0, this.conObj.offsetWidth - 
                    sFire.offsetWidth);
                //调用运动函数
                this.move(sFire, {
                    top,
                    left }, function () {
                    sFire.remove();
                })
            }
        }


        //封装一个公共的运动函数方法
        // let times = '';
        Fire.prototype.move = function (ele, target, way) {
            // clearInterval(times);
            times = setInterval(function () {
                var onOff = true;
                //遍历运动的方向和目标(即遍历target)
                for (let attr in target) { //attr表示运动的属性
                    //获取元素运动到哪里了的实时值
                    //想要获取实时值,就要现在外部封装一个获取实时位置的函数方法,然后 
                      再通过这个方法获取实时值
                    let now = parseInt(this.getPos(ele, attr))
                    //计算此时速度的值(speed)
                    let speed = (target[attr] - now) / 10;
                    //取整数(向上向下取整)
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

                    //设置一个开关的状态(true)用来表示元素运动到终点
                    if (now == target[attr]) {
                        onOff = true;
                    }
                    //让元素运动
                    ele.style[attr] = now + speed + 'px';
                }

                //判断开关的状态,如果到达终点则停止定时器
                for (var tip in target) {
                    if (target[tip] !== parseInt(this.getPos(ele, tip))) {
                        onOff = false;
                        break;
                    }
                }
                if (onOff) {
                    clearInterval(times);
                    way && way();
                }
                
            }.bind(this), 30) //使用bind更改this指向
        }
        //封装一个函数方法来获取元素的实时位置
        Fire.prototype.getPos = function (obj, attr) {
            //currentStyle和getComputedStyle都是获取元素的全部css样式,分别是兼容写法

            if (obj.currentStyle) {
                return obj.currentStyle[attr]
            } else {
                return getComputedStyle(obj)[attr]
            }
        }

        /*****封装一个公共的获取随机数的函数方法*****/ //箭头函数???
        Fire.prototype.rand = (min, max) => {
            return Math.round(Math.random() * (max - min) + min)
        }

        /********封装一个公共的设置随机颜色的函数方法*******/
        Fire.prototype.getColor = function () {
            let c = '#';
            for (let i = 0; i < 6; i++) {
                c += this.rand(0, 15).toString(16) //
                // console.log(this);  //this指向当前节点对象(Fire)
            }
            return c;
        }
    </script>
</body>

</html>

运行效果感兴趣的可以自行copy运行,有误之处欢迎大家指教交流~~~~3Q

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值