IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JavaScript实现运动函数的封装(抛物) -> 正文阅读

[JavaScript知识库]JavaScript实现运动函数的封装(抛物)

????????当今的生活质量越来越高,人们对于自身的身体素质也更加重视。对于运动的热情,逐渐高涨起来。

? ? ? ? 人类的体育锻炼运动中,看见最多的就是篮球了吧。本人不会打篮球,因为篮球看着太吓人, 我的小身板也不允许我去打篮球,打篮球的过程中总会有磕磕撞撞,导致受伤。

? ? ? ? 篮球运动的规则不就是,把球扔进篮球篮子嘛。so eazy 。再换句话说不就是大家都知道的抛物运动嘛。

? ? ? ? 提到抛物运动,回想起高中物理,是不是大家对于打篮球就充满了‘自信’。手抬高,一扔,进了!!!

今天介绍的也是抛物运动的实现,不过不是在生活中实现它。而是在页面中实现它,而实际上在也页面上投篮的就是JavaScript。它才是本场比赛的篮球运动员。

?

?在讲抛物线运动之前,要明白抛物线运动的实质。或者将其分解为两个方向的运动。

? ? ? ? 1.首先是竖直方向上的运动,就是单纯的高度逐渐减小的过程

? ? ? ? 2.其次就是水平方向上的运动,也就是单纯的往一个方向位移过程。

? ? ? ? ? ? ? ? 将这两个分支运动合起来就是我们的打篮球了。

? ?让我们的JavaScript上场表演吧!!!

?垂直方向:

? ? ? ? 垂直方向的运动,在页面中就是高度的减小。

? ? ? ? 下面是一个简单的例子:篮球的重力回弹的效果。

????????????????

?第一阶段的过程就是球的下落过程,也就是球的高度top的不断增大。

? ? ? ? 在top值增大的过程中也就需要,不断地给top增加一个speed步进值。

? ? ? ? ? ? ? ? 先是基本的css和html样式和结构? ? ? ??

<style type="text/css">
        .cont {
            width: 1000px;
            height: 600px;
            background: #eee;
            margin: 20px auto;
            position: relative;
        }
        
        .box {
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 0;
            border-radius: 50%;
        }
    </style>
<body>
    <div class="cont">
        <div class="box"></div>
    </div>
</body>

?接下来就是我们今天的主角:JavaScript登场啦!!!

? ? ? ? 第一步是获取html当中的节点对象,才能进行操作。

<script>
    // 1 获取节点
    let contObj = document.querySelector('.cont');//篮球可以活动的范围,节点对象
    let boxObj = document.querySelector('.box');//篮球节点对象
</script>

? ? ? ? 第二步进行我们所需要的变量的声明准备。

? ? ? ? ? ? ? ? 其中重要的变量有:

? ? ? ? ? ? 1. 因为地球的原因,有重力,所以在步进值speed的基础上,应该还要增加重力带来的加速度。

? ? ? ? ? ? ?2.target目标,就是篮球在范围内最大的可运动的高度(要减去球自身的高度)。

? ? ? ? ? ? 3.要想让球的高度减少,就应该让球在反向的时候,让它的speed比原来小就可以了,所以给speed乘以一个小于1的数,就可以让反向高度变小。

// 2 设置变量
    let speed = 10; //步进值
    let g = 2; //重力的影响
    let times = ''; //清除定时器的标识符
    let target = contObj.offsetHeight - boxObj.offsetHeight; // 小球的最大目标值

第三步就是具体的实现方法 :

//球绑定点击事件
    ball.addEventListener('click', function() {
        clearInterval(timer) //防止定时器累加
        timer = setInterval(function() { //设置定时器
            speed += g; //步长增加
            if (speed < target - ball.offsetTop) { //高度小于目标高度时
                ball.style.top = ball.offsetTop + speed + 'px'; //设置球的高度样式
            } else if (speed >= target - ball.offsetTop) { //当到盒子目标高度时
                ball.style.top = target + 'px'; //让球直接到达底部
                speed = -parseInt(speed) * 0.8; //让步长变负,高度减小,球往上走
                if (Math.abs(speed) < 1) { //当步长小于1
                    clearInterval(timer); //停止
                }
            }
        }, 30)
    })

?完成上述的垂直方向的运动之后,就可以往其加上水平方向的代码了。

垂直方向和水平方向的结合:

? ? ? ? 水平方向的原理其实和垂直方向差不多,你也可以想象将页面顺时针旋转90度。

? ? ? ? 实现方法:

? ? ? ? 第一步获取节点对象,同上。

? ? ? ? 第二步准备需要的变量。因为要在水平方向上变化,肯定也需要一个水平的步进值,leftSpeed,也同样需要往左的最大范围值leftTarget,也是?篮球在范围内最大的可运动的宽度再减去球本身的宽度。增加了一个count值用来,累积运动次数,每5次增加一个重力,让它能跳更久,到底部的时间增加。

// 设置left的步进值和最大值
    var leftSpeed = 20;
    var leftTarget = 1000 - ballObj.offsetWidth;
    var count = 0; // 累计运动次数

? ? ? ? ?第三步,只需要给球在高度样式的位置添加水平位移样式即可

ballObj.style.left = leftSpeed + ballObj.offsetLeft + 'px'; //给球位移样式

在这里需要注意:?

? ? ? ? 球可能会从水平方向滚出去。所以还需要给球设置边界:

? ? ? ? 思路其实很简单:只需要等球到达可运动范围的最大值的时候,让它的步进值反向

            if (ballObj.offsetLeft >= leftTarget) { //当球到达最右边届
                leftSpeed = -leftSpeed; //步进值反向
            }
            if (ballObj.offsetLeft <= 0) { //当球到达最右边届
                leftSpeed = -leftSpeed; //步进值反向
            }

?综上实现得到的代码 :

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }
        
        .box {
            width: 1000px;
            height: 400px;
            margin: 50px auto;
            position: relative
        }
        
        #ball {
            width: 50px;
            height: 50px;
            background: red;
            border-radius: 50%;
            position: absolute;
            left: 0px;
            top: 0;
        }
        
        .line {
            width: 1000px;
            height: 1px;
            background: black;
            position: absolute;
            top: 300px;
            left: 0px;
        }
    </style>
</head>

<body>
    <div class="box">
        <div id="ball"></div>
        <div class="line"></div>
    </div>
</body>
<script type="text/javascript">
    // 1 获取节点
    var ballObj = document.getElementById('ball');
    var lineObj = document.querySelector('.line')
        // 2 设置top的步进值,和最大值.
        // 定时器的计数器
    var topSpeed = 5;
    var topTarget = 300 - ballObj.offsetHeight; // top的临界值
    var count = 0; // 累计运动次数
    var g = 1; // 重力值的设置

    // 设置left的步进值和最大值
    var leftSpeed = 20;
    var leftTarget = 1000 - ballObj.offsetWidth;
    //定时器标识
    var times = '';

    ballObj.onclick = function() {
        clearInterval(times); //清除定时器累加
        times = setInterval(function() {
            count++;
            if (count % 5 == 0) { //运动5次增加一个重力
                topSpeed += g; //高度步进增加
            }
            if (topSpeed + ballObj.offsetTop > topTarget) { //当大于目标值
                topSpeed = -topSpeed * 0.8; //步进变负,上升
                ballObj.style.top = topTarget; //强制到最下面
                if (Math.abs(topSpeed) < 1) clearInterval(times); //步进值小于1,清除定时器
            } else {
                ballObj.style.top = topSpeed + ballObj.offsetTop + 'px'; //给球下降的样式
                ballObj.style.left = leftSpeed + ballObj.offsetLeft + 'px'; //给球位移样式
            }
            if (ballObj.offsetLeft >= leftTarget) { //当球到达最右边届
                leftSpeed = -leftSpeed; //步进值反向
            }
            if (ballObj.offsetLeft <= 0) { //当球到达最右边届
                leftSpeed = -leftSpeed; //步进值反向
            }
        }, 30)
    }
</script>

</html>

前两个例子大同小异,方法基本相同。所以可以想办法封装一个运动函数。

? ? ? ? 运动函数的目的就是,只要输入运动的三要素{谁运动,运动方向,目标值}。我们就能实现运动效果。

? ? ? ? 其中获取元素的实时属性的时候,需要考虑是否是行内样式。如果不是行内样式,要添加兼容性获取样式的封装函数

        // 获取元素的非行内样式的封装函数
        function getPos(obj, attr) {//参数为对象,和属性
            if (obj.currentStyle) { // 获取css的样式
                return obj.currentStyle[attr];
            } else {
                return getComputedStyle(obj)[attr]
            }
        }

?得到元素的实时位置之后就可以进行下一步封装运动函数了。

var times = '';

        function move(ele, obj, back) { //运动函数
            clearInterval(times); //清除定时器,以免累加
            times = setInterval(function() { //定时器
                var onOff = true;
                for (let index in obj) { //遍历对象中的所有属性,index代表属性
                    var value = parseInt(getPos(ele, index)); //获取元素属性对应的样式的实时值
                    var speed = (obj[index] - value) / 10; //设置步进值
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //取整,方便计算
                    if (value == obj[index]) onOff = true; // 当一个属性运动到位置,设置开关状态
                    ele.style[index] = value + speed + 'px'; //设置元素的样式
                }
                for (var i in obj) { //再次遍历对象中的所有属性
                    if (obj[i] !== parseInt(getPos(ele, i))) { //如果存在实时值和目标值不相等。
                        onOff = false; //开关状态为假
                        break;
                    }
                }
                if (onOff) { //开关为真,则清除定时器
                    clearInterval(times);
                    back && back(); //调用回调函数
                }
            }, 30)
        }
        // 获取元素的非行内样式的封装函数
        function getPos(obj, attr) {
            if (obj.currentStyle) { // 获取css的样式
                return obj.currentStyle[attr];
            } else {
                return getComputedStyle(obj)[attr]
            }
        }

调用封装运动函数的方法:?

? ? ? ? ?首先应该得到一个目标值(可以是任何数据)。target

? ? ? ? 再比如给一个按钮绑定点击事件,开始运动。同样需要运动三要素

? ? ? ? ele为要运动元素名,第二个参数为对象,对象中是需要运动的属性和属性值,最后是回调函数,回调函数可以根据情况添加或者不加。

        btn.onclick = function() {
            move(ele, {
                left: target,
                height: 300
            }, function() {})
        }

?有了运动函数就可以随意添加变化的属性值了,再也不用担心要添加的变量多了!

举一个使用封装运动函数实现的例子:

? ? ? ? ?第一个要求:让红色方块移动到黑色竖线。

? ? ? ? 第二个要求:在移动的过程中方块的高度要变化到300px。

实现步骤:

? ? ? ? 1.首先是移动的元素是:方块。

? ? ? ? 2.变化的属性:方块的height,方块距离屏幕的left值。

? ? ? ? 3.目标值:height的目标值就是300px,left的目标值设为target就应该是方块的offsetLeft值减去竖线的offsetLeft值。

// 1 获取节点
        let btnObj = document.getElementById('btn'); //获取按钮节点对象
        let divObj = document.querySelector('div'); //获取方块节点对象

        // 目标值
        let target = divObj.offsetLeft - divObj.nextElementSibling.offsetLeft;

        //给按钮绑定点击事件
        btnObj.onclick = () => {
            //调用移动函数
            move(divObj, {
                left: target,
                height: 300
            }, function() {
                console.log('移到目标啦!!!');

            })
        }

?再将上面封装好的运动函数,加到点击事件后面即可完成。

运动函数的封装就完成了!

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:37:59  更:2021-09-08 10:40:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 20:34:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计