原生js的弹力小球

有段日子没发博客了,今天来一弹。

这次发的东西,难度比较大,用原生js,写的一个弹力小球,而且是群发,下面是一张截图。

每一次点击“添加小球”,都会触发程序,新创造一个div盒子、定义css样式,然后塞进大盒子中。

接着,给这个div小球创造一个定时器,让他开始移动,并且在碰到墙壁时,会停止匀速运行的定时器,执行另一个函数,开启变速移动的定时器,同时对div小球开启进行变形定时器,实现碰到墙壁后的减速、变形、改变方向、再加速和恢复体形。

讲述原理比较简单,而真正做起来,就麻烦了。

程序中事先声明了很多数组,每个数组,分别用来保存小球的轴向速度、定时器、碰到墙壁时的定时器、判读是否碰到了墙壁、碰到墙壁时的宽度和高度的尺寸等等,太多了。数组中的每一项,对应不同的小球,很麻烦。

试想过,把每个小球封装成一个对象,毕竟js是基于对象的语言,但是一琢磨,发现改起来还不是个小工程,也就放弃了这个打算,还是以后再有好玩儿的案例,事先想好吧。

下面是这个程序运行时的动态图,再下面,就是完整代码了,和之前的一样,直接整个复制,保存到txt,然后改后缀名为html,再双击用浏览器打开,就可以玩儿了。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        #ballBox {
            position: relative;
            margin: 0 auto;
            overflow: hidden;
            background-color: #000;
        }
        #ballBox div {
            text-align: center;
            font-family: "微软雅黑";
            font-weight: bold;
            color: #fff;
        }
        #ballBox button {
            outline:none;
            cursor: pointer;
            border:none;
            background-color: #fff;
            height: 50px;
            position: absolute;
            padding: 0 10px;
            top: 20px;
            left: 50%;
            font: 20px "微软雅黑";
            margin-left: -70px;
            z-index: 5;
        }
        #ballBox button:active {
            background-color: #bbb;
        }
    </style>
</head>
<body>
<div id="ballBox">
    <button>添加小球(0)</button>
</div>
</body>
<script>
    var ballBox = document.getElementById("ballBox");
    var ballBtn = ballBox.getElementsByTagName("button")[0];
    var div = ballBox.getElementsByTagName("div");
    var timerX = []; //x方向 定时器
    var timerY = []; //y方向 定时器
    var timerXX = []; //x方向碰壁反弹时的定时器
    var timerYY = []; //y方向碰壁反弹时的定时器
    var positionX = [];  //设置这个小球的位置的初始的X轴坐标
    var positionY = [];  //设置这个小球的位置的初始的y轴坐标
    var boolX = [];  //用来判断小球是否碰到过墙壁,用不用反方向
    var boolY = [];  //用来判断小球是否碰到过墙壁,用不用反方向
    var i = []; // 小球碰到墙壁,减速加速时使用
    var width = [];   //小球碰到墙壁时,每次运行定时器时小球的宽度
    var height = [];      //小球碰到墙壁时,每次运行定时器时小球的高度
    var initialW = document.documentElement.clientWidth;  //小球弹跳区域的大小,这里设置的是可视区域
    var initialH = document.documentElement.clientHeight;  //小球弹跳区域的大小,这里设置的是可视区域
    ballBox.style.width = initialW + "px";
    ballBox.style.height = initialH + "px";
    var num = 0;// 用来记录新生成小球的个数,同时作为小球的索引值
    var number = [];  //用来记录小球撞过几次墙壁
    var colorArr = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]; //用来生成随机颜色
    ballBtn.onclick = function() {
        ballBtn.innerHTML = "添加小球("+ (num+1) +")";
        var color = "";//用来随机生成颜色
        for (var i = 0; i < 6; i++) {
            color += colorArr[Math.floor(Math.random()*16)];
        }
        var temp = [];  //临时数组,用来放三个随机数
        do {
            temp[0] = Math.random()*60;
        }while(temp[0] < 35)  //生成一个随机数,用来做为小球的直径;
        do {
            temp[1] = Math.random()*4;
        }while(temp[1] < 1)  //生成一个随机数,用来做为小球x方向的步长;
        do {
            temp[2] = Math.random()*4;
        }while(temp[2] < 1)  //生成一个随机数,用来做为小球y方向的步长;
        var newDiv = document.createElement("div");
        newDiv.style.position = "absolute";  //设置小球的一系列属性,大小,颜色等等
        newDiv.style.width = temp[0] + "px";
        newDiv.style.height = temp[0] + "px";
        newDiv.style.borderRadius = "50%";
        newDiv.style.backgroundColor = "#" + color ;
        newDiv.style.top = 0;
        newDiv.style.left = 0;
        newDiv.title = num++;  //设置索引
        newDiv.style.fontSize = temp[0]/2 + "px";
        newDiv.style.lineHeight = temp[0] + "px";
        number[number.length] = 0;
        newDiv.innerHTML = number[number.length - 1];
        positionX[positionX.length] = 0;  //设置这个小球的位置的初始的X轴坐标也就是小球出发的位置
        positionY[positionY.length] = 0;  //设置这个小球的位置的初始的y轴坐标也就是小球出发的位置
        boolX[boolX.length]= false;  //用来判读小球是否碰到过墙壁,用不用反方向
        boolY[boolY.length]= false;  //用来判读小球是否碰到过墙壁,用不用反方向
        ballBox.appendChild(newDiv);
        timerX[timerX.length] = setInterval("moveX("+temp[0]+","+temp[1]+","+ (div.length-1) +")",10);
        timerY[timerY.length] = setInterval("moveY("+temp[0]+","+temp[2]+","+ (div.length-1) +")",10);
    }
    document.onkeydown = function() {   //按下键盘事件
        ballBtn.onclick();
        ballBtn.style.backgroundColor = "#bbb";
    }
    document.onkeyup = function() {   //按下键盘事件
        ballBtn.style.backgroundColor = "#fff";
    }
    function moveX(dia,x,index) {      //小球x轴方向的位移函数
        if (positionX[index]+x > initialW-dia) {  //if用来判断小球是否需要换方向
            clearInterval(timerX[index]);
            div[index].style.left = "";
            div[index].style.right =  "0";
            i[index] = 0;
            number[index]++;
            div[index].innerHTML = number[index];
            timerXX[index] = setInterval("fn("+x+","+index+ ","+ dia +",‘right‘)",10);
            return;
        }
        if (positionX[index]+x < 0) {  //if用来判断小球是否需要换方向
            clearInterval(timerX[index]);
            div[index].style.left = "0";
            i[index] = 0;
            number[index]++;
            div[index].innerHTML = number[index];
            timerXX[index] = setInterval("fn("+x+","+index+ ","+ dia +",‘left‘)",10);
            return;
        }
        positionX[index] += x;
        div[index].style.left =  positionX[index] + "px";  //设定此小球距离左端的距离
    }
    function moveY(dia,y,index) {      //小球y轴方向的位移函数
        if (positionY[index]+y > initialH-dia) {  //if用来判断小球是否需要换方向
            clearInterval(timerY[index]);
            div[index].style.top = "";
            div[index].style.bottom =  "0";
            i[index] = 0;
            number[index]++;
            div[index].innerHTML = number[index];
            timerYY[index] = setInterval("fn("+y+","+index+ ","+ dia +",‘bottom‘)",10);
            return;
        }
        if (positionY[index]+y < 0) {  //if用来判断小球是否需要换方向
            clearInterval(timerY[index]);
            div[index].style.top = "0";
            i[index] = 0;
            number[index]++;
            div[index].innerHTML = number[index];
            timerYY[index] = setInterval("fn("+y+","+index+ ","+ dia +",‘top‘)",10);
            return;
        }
        positionY[index] += y;
        div[index].style.top =  positionY[index] + "px";   //设定此小球距离顶端的距离
    }
    function fn(k,index,dia,direction) {
        width[index] = div[index].scrollWidth;
        height[index] = div[index].scrollHeight;
        k = -k;
        //  判断是否已经反弹完成,该脱离墙壁了
        if ( -(Math.abs(k)+i[index]) > Math.abs(k)) {
            div[index].style.width = dia + "px";        //使宽高均为原始大小
            div[index].style.height = dia + "px";       //使宽高均为原始大小
            //判断是左右方向撞墙还是上下方向,需要调用不同的定时器
            if (direction == "left"||direction == "right") {
                clearInterval(timerXX[index]);
                timerX[index] = setInterval("moveX("+dia+","+k+","+ index +")",10);
                return ;
            }else {
                clearInterval(timerYY[index]);
                timerY[index] = setInterval("moveY("+dia+","+k+","+ index +")",10);
                return ;
            }
        }
        i[index] -= 0.4;
        if (direction == "left") {
            k += i[index];
            var width2 = width[index] - k;
            var height2 = height[index] + k;
        }else if (direction == "right"){
            k -= i[index];
            var width2 = width[index] + k;
            var height2 = height[index] - k;
        }else if (direction == "top") {
            k += i[index];
            var width2 = width[index] + k;
            var height2 = height[index] - k;
        }else{
            k -= i[index];
            var width2 = width[index] - k;
            var height2 = height[index] + k;
        }
        div[index].style.width = width2 + "px";
        div[index].style.height = height2 + "px";
    }
</script>
</html>

<!--加速度的定义是△v/△t,这是一般的求法-->
<!--还有就是利用牛顿第二定律,F=ma,可以先求合外力,再比上质量就是加速度a-->
<!--还可以利用运动学公式X=1/2at2+v0t或者v2-v02=2ax求出-->
时间: 2024-10-17 02:31:42

原生js的弹力小球的相关文章

利用原生JS实现网页1920banner图滚动效果

内容描述:随着PC设备硬件性能的进步和分辨率的不断提高,现在主流网站逐渐开始采用1920banner图,为适应这一趋势,博主设计了1920banner图的滚动效果,代码利用了原生JS实现了1920banner图的切换效果,并针对低分辨率电脑设备进行了适配,实现了JS代码与HTML代码的完全分离,符合w3c的标准使用规范,希望能给各位开发者朋友以帮助和参考.如发现有缺陷和不足,欢迎大家予以指正,如有更好的意见或解决方法,可在评论区交流互动.一下为代码内容: <!DOCTYPE html> <

原生JS写的ajax函数

参照JQuery中的ajax功能,用原生JS写了一个ajax,功能相对JQuery要少很多,不过基本功能都有,包括JSONP. 调用的方式分为两种: 1. ajax(url, {}); 2. ajax({}); 调用的方法参照JQuery的ajax,只是 不需要写$.ajax ,只需要写 ajax 就可以了. 代码如下: !function () { var jsonp_idx = 1; return ajax = function (url, options) { if (typeof url

原生js自动触发事件

熟悉jquery的童鞋都知道在jq中有一个方法可以自动触发事件,那就是trigger(),那么通过原生js又怎么模拟触发呢? js中添加一个主动触发事件的方法有dispatch.该方法能模拟用户行为,如点击(click)操作等. 标准使用dispatchEvent方法,IE6/7/8则使用fireEvent方法. dispatchEvent() 方法给节点分派一个合成事件. 语法如下: dispatchEvent(eventObj) eventObj 参数是一个描述事件的 ActionScrip

使用原生js的scrollTop,刷新进入页面定位到某一个dom元素

原生js的scrollTop即可,与jquery方法的区别是jquery做了兼容封装.我想要实现的功能是时间定位,根据当前时间定位到滚动区的时间位置.页面为移动端页面,上下固定位置,中部为1小时4格的选择区域,从0点到24点. 开始我想发出现了偏差,总想定位到某个dom,这样使得scrollTop一直是0,怎么设置都不行,后来仔细分析才发现要设置在超出当前可视区域的dom上才可以. 所以设置在外层overflow-x:scroll;的dom上即可,根据时间匹配dom位置,根据索引及每格的高度计算

原生JS封装运动框架

昨天我们说了一下原生JS中常用的兼容性写法,今天我们来说一下运动框架. 正常情况下我们要写一个运动的效果会用到tween.js这么一个插件,这个东西不是一般人写出来的,因为里面涉及的运动效果都是经过一堆数学的函数运算出来的,我们平常人是写不出来的,所有我们就自己封装一个运动框架,有什么问题改起来也方便,下面我们就开始封装. 首先,我们先写一个div,设置一些简单的样式,我们就拿这个div举例子,如下代码: #div{ width: 100px; height: 100px; background

常用原生JS兼容写法

在我们前端开发中,经常会遇到兼容性的问题,因为要考虑用户会使用不同的浏览器来访问你的页面,你要保证你做的网页在任何一个浏览器中都能正常的运行,下面我就举几个常用原生JS的兼容写法: 1:添加事件方法 addHandler:function(element,type,handler){  if(element.addEventListener){//检测是否为DOM2级方法   element.addEventListener(type, handler, false);  }else if (e

原生js实现数据双向绑定

最近接触了vue,在谈到vue等等的mvvm框架之前,先了解什么是数据双向绑定以及如何利用原生JS实现数据双向绑定 单向数据绑定 指先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里 缺点:一旦HTML代码生成就没有办法改变,如果有新数据重新传入,就必须重新把模板和数据整合到一起插入到文档流中 数据双向绑定 数据模型和视图之间的双向绑定,用户在视图上的修改会自动同步到数据模型中,同样的,如果数据模型中的值发生变化,也会同步到视图中去

原生JS与jQuery操作DOM有什么异同点?

本文和大家分享的主要是原生JS与jQuery操作DOM相关内容,一起来看看吧,希望对大家学习javascript有所帮助. 一.创建元素节点 1.1 原生 JS 创建元素节点 document.createElement("p"); 1.2 jQuery 创建元素节点 $('<p></p>');` 二.创建并添加文本节点 2.1 原生JS创建文本节点 document.createTextNode("Text Content"); 通常创建文

原生 js 左右切换轮播图

使用方法: 可能很多人对轮播图感兴趣,下面奉上本人的 原生 js 轮播代码复制 js 到页面的最底部,样式在 css 里改,js 基本不用动,有什么不懂的可以 加本人 QQ172360937 咨询 或者留言都可以,这个是用 原生写的 轮播图,样式可以写自己喜欢的样式,什么都不用改,只改变样式就行,页面结构的id 要与js的相对应li随便加.li 随便加的意思就是说你可以加无数个图片.每个li 里装一个图片,或者是其他什么元素, <!doctype html> <html lang=&qu