javascript运动系列第三篇——曲线运动

×

目录

[1]圆周运动 [2]钟摆运动 [3]抛物线运动

前面的话

  上一篇介绍了变速运动,但只实现了直线运动。如果元素的left和top同时运动,并遵循不同的曲线公式,则会进行不同形式的曲线运动。本文将详细介绍圆周运动、钟摆运动和抛物线运动这三种曲线运动形式

圆周运动

  圆周运动可能是最好理解的曲线运动了

  若(x0,y0)为圆心,则圆的公式为(x-x0)*(x-x0) + (y-y0)*(y-y0) = r*r

  写成三角函数的形式为

    x = x0 + cosa*r
    y = y0 + sina*r

  所以,实际上只要知道夹角a和圆心(x0,y0)就可以计算出x和y

  圆周运动可以封装为函数circleMove.js

function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
}
function circleMove(json){
    //要操作的元素
    var obj = json.obj;
    //方向(顺时针‘+‘或逆时针‘-‘)
    var dir = json.dir;
    dir = dir || ‘+‘;
    //最大圈数
    var max = json.max;
    max = Number(max) || ‘all‘;
    //半径
    var r = json.r;
    r = Number(r) || 100;
    //圆心x轴坐标
    var x0 = json.x0 || parseFloat(getCSS(obj,‘left‘));
    //圆心y轴坐标
    var y0 = json.y0 ||  parseFloat(getCSS(obj,‘top‘)) - r;
    //初始夹角,以角度为单位
    var a0 = json.a0;
    a0 = Number(a) || 90;
    //当前夹角
    var a = json.a ||a0;
    //当前圈数
    var num = json.num || 0;
    //清除定时器
    if(obj.timer){return;}
    //声明当前值cur
    var cur = {};
    obj.timer = setInterval(function(){
        //将这些瞬时值储存在obj对象中的属性中
        obj.a = a;
        obj.x0 = x0;
        obj.y0 = y0;
        obj.x = x;
        obj.y = y;
        obj.num = num;
        //如果元素运动到指定圈数则停止定时器
        if(num == max){
            clearInterval(obj.timer);
        }
        //顺时针
        if(dir == ‘+‘){
            a++;
            if(a == a0 + 360){
                a = a0;
                num++;
            }
        //逆时针
        }else{
            a--;
            if(a == a0 - 360){
                a = a0;
                num++;
            }
        }
        //更新当前值
        cur.left = parseFloat(getCSS(obj,‘left‘));
        cur.top = parseFloat(getCSS(obj,‘top‘));
        //更新left和top值
        var x = x0 + r*Math.cos(a*Math.PI/180);
        var y = y0 + r*Math.sin(a*Math.PI/180)
        test.style.left = x + ‘px‘;
        test.style.top = y + ‘px‘;
    },20);
}

  下面利用封装的circleMove.js来实现简单的圆周运动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button id="btn1">顺时针旋转</button>
<button id="btn2">逆时针旋转</button>
<button id="btn3">暂停</button>
<button id="reset">还原</button>
<div id="result"></div>
<div id="backup" style="height: 298px;width:298px;border:1px solid black;border-radius:50%;position:absolute;top:50px;left:50px;">
    <div id="test" style="height: 40px;width: 40px;background-color:pink;position:relative;left:130px;top:280px;border-radius:50%"></div>
</div>
<script src="http://files.cnblogs.com/files/xiaohuochai/circleMove.js"></script>
<script>
reset.onclick = function(){
    history.go();
}
btn1.onclick = function(){
    circleMove({obj:test,r:150,x0:test.x0,y0:test.y0,a:test.a,num:test.num});
}
btn2.onclick = function(){
    circleMove({obj:test,r:150,dir:‘-‘,x0:test.x0,y0:test.y0,a:test.a,num:test.num});
}
btn3.onclick = function(){
    clearInterval(test.timer);
    test.timer = 0;
}
</script>
</body>
</html>

钟摆运动

  一个钟摆,一会儿朝左,一会儿朝右,周而复始,来回摆动。钟摆总是围绕着一个中心值在一定范围内作有规律的摆动,这种运动称为钟摆运动,可以把钟摆运动看做圆周运动的一部分,进而比较简单的实现钟摆运动

  假设,元素初始时处于钟摆的最底点。当钟摆与竖直线夹角为60度时,为最高点

  若钟摆运动的圆心为(x0,y0),则圆的公式为(x-x0)*(x-x0) + (y-y0)*(y-y0) = r*r

  若夹角a为钟摆与竖直线夹角,写成三角函数的形式为

    x = x0 + sina*r
    y = y0 + cosa*r

  当夹角a从0增加到60或减小到-60时,元素开始做反向运动

  将钟摆运动写成pendulMove.js的形式

function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
}
function pendulMove(json){
    //要操作的元素
    var obj = json.obj;
    //起始方向(顺时针‘+‘或逆时针‘-‘)
    var dir = json.dir;
    dir = dir || ‘+‘;
    //最大次数(再次经过最低点为一次)
    var max = json.max;
    max = Number(max) || ‘all‘;
    //半径
    var r = json.r;
    r = Number(r) || 100;
    //圆心x轴坐标
    var x0 = json.x0 || parseFloat(getCSS(obj,‘left‘));
    //圆心y轴坐标
    var y0 = json.y0 ||  parseFloat(getCSS(obj,‘top‘)) - r;
    //初始夹角,以角度为单位
    var a0 = json.a0;
    a0 = Number(a) || 0;
    //当前夹角
    var a = json.a ||0;
    //当前次数
    var num = 0;
    //清除定时器
    if(obj.timer){return;}
    //声明当前值cur
    var cur = {};
    obj.timer = setInterval(function(){
        //将这些瞬时值储存在obj对象中的属性中
        obj.a = a;
        obj.x0 = x0;
        obj.y0 = y0;
        obj.x = x;
        obj.y = y;
        obj.num = num;
        //如果元素运动到指定圈数则停止定时器
        if(num == max){
            clearInterval(obj.timer);
        }
        //起始向右运动
        if(dir == ‘+‘){
            a++;
            if(a == 60){
                //方向变成向左
                dir = ‘-‘;
            }
        }else{
            a--;
            if(a == -60){
                //方向变成向右
                dir = ‘+‘;
            }
        }
        //更新当前值
        cur.left = parseFloat(getCSS(obj,‘left‘));
        cur.top = parseFloat(getCSS(obj,‘top‘));
        //更新left和top值
        var x = x0 + r*Math.sin(a*Math.PI/180);
        var y = y0 + r*Math.cos(a*Math.PI/180)
        test.style.left = x + ‘px‘;
        test.style.top = y + ‘px‘;
    },20);
}

  下面利用封装的pendulMove.js来实现简单的钟摆运动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button id="btn1">起始正向运动</button>
<button id="btn2">起始逆向运动</button>
<button id="btn3">暂停</button>
<button id="reset">还原</button>
<div id="result"></div>
<div id="backup" style="height: 298px;width:298px;border-bottom:1px solid black;border-radius:50%;position:absolute;top:50px;left:50px;">
    <div id="test" style="height: 40px;width: 40px;background-color:pink;position:relative;left:130px;top:280px;border-radius:50%"></div>
</div>
<script src="http://files.cnblogs.com/files/xiaohuochai/pendulMove.js"></script>
<script>
reset.onclick = function(){
    history.go();
}
btn1.onclick = function(){
    pendulMove({obj:test,r:150,x0:test.x0,y0:test.y0,a:test.a,num:test.num});
}
btn2.onclick = function(){
    pendulMove({obj:test,r:150,dir:‘-‘,x0:test.x0,y0:test.y0,a:test.a,num:test.num});
}
btn3.onclick = function(){
    clearInterval(test.timer);
    test.timer = 0;
}
</script>
</body>
</html>

抛物线运动

  平面内到定点与定直线的距离相等的点的轨迹叫做抛物线。其中定点叫抛物线的焦点,定直线叫抛物线的准线。抛物线实际上就是一段特殊形式的曲线

  抛物线方程为y=a*x*x+b*x+c

  其中a、b、c为参数,以x为参照的话,当x以固定值递增的方式进行变化时,y也会有相应变化

  若a>0时,抛物线的开口向下;否则,开口向上

  抛物线的准线的x轴坐标为(-2*a/b)。如果target目标设置为100,则(-2*a/b)尽量设置为50

  若a = 0.01,则b=-1

  将抛物线运动写成parabolMove.js的形式

function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
}
function parabolMove(json){
    //设置要操作的元素
    var obj = json.obj;
    //设置x轴上的目标值
    var target = json.target;
    target = Number(target) || 300;
    //设置x轴的步长值
    var stepValue = json.step || 2;
    //设置x轴的步长
    var step = 0;
    //设置回调函数
    var fn = json.fn;
    //参数a、b、c
    var a = json.a;
    a = Number(a) || 0.01;
    var b = json.b;
    b = Number(b) || -1*target/100;
    var c = json.c;
    c = Number(c) || 0;
    //初始值
    var left = parseFloat(getCSS(obj,‘left‘));
    if(left >= target){return;}
    var top = parseFloat(getCSS(obj,‘top‘));
    //清除定时器
    if(obj.timer){return;}
    //声明当前值cur
    var cur = {};
    obj.timer = setInterval(function(){
        //更新步长值
        step += stepValue;
        //更新left和top值
        var x = left + step;
        var y = top + a*step*step + b*step + c;
        if(x > target){
            x = target;
        }
        test.style.left = x + ‘px‘;
        test.style.top = y + ‘px‘;
        //如果到达目标点,清除定时器
        if(x == target){
            clearInterval(obj.timer);
            obj.timer = 0;
            fn && fn.call(obj);
        }
    },20);
} 

  下面利用封装的parabolMove.js来实现简单的抛物线运动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button id="btn1">开始运动</button>
<button id="reset">还原</button>
<div id="test" style="height: 40px;width: 40px;background-color:pink;position:absolute;left:0px;top:100px;"></div>

<script src="http://files.cnblogs.com/files/xiaohuochai/parabolMove.js"></script>
<script>
reset.onclick = function(){
    history.go();
}
btn1.onclick = function(){
    parabolMove({obj:test,target:200});
}

</script>
</body>
</html>
时间: 2024-10-24 15:07:03

javascript运动系列第三篇——曲线运动的相关文章

深入理解javascript函数系列第三篇

前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数系列第三篇--属性和方法 属性 [length属性] 函数系列第二篇中介绍过,arguments对象的length属性表示实参个数,而函数的length属性则表示形参个数 function add(x,y){ console.log(arguments.length)//3 console.log(

深入理解javascript作用域系列第三篇

前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇--声明提升(hoisting) 变量声明提升 a = 2 ; var a; console.log( a ); 直觉上,会认为是undefined,因为var a声明在a = 2;之后,可能变量被重新赋值了,因为会被赋予默认值undefined.但是,真正的输出结果是2 console.log( a ) ; var a

深入理解javascript作用域系列第三篇——声明提升(hoisting)

× 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇——声明提升(hoisting) 变量声明提升 a = 2 ; var a; console.log( a ); 直觉上,会认为是undefined,因为var a声明在a = 2;之后,可能变量被重新赋值了,因为会被赋予默认值undefined.但是,真正的输出结果是2 c

javascript面向对象系列第三篇——实现继承的3种形式

前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.开宗明义,继承是指在原有对象的基础上,略作修改,得到一个新的对象.javascript主要包括类式继承.原型继承和拷贝继承这三种继承方式.本文是javascript面向对象系列第三篇——实现继承的3种形式 类式继承 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,如new和instanceof.不过在后来的ES6中新增了一些元素,比如class关键字,但这并不

javascript运动系列第七篇——鼠标跟随运动

× 目录 [1]眼球转动 [2]苹果菜单 前面的话 运动除了直线运动和曲线运动两种运动形式外,还有一种运动形式是鼠标跟随运动,而这种跟随运动需要用到三角函数的相关内容或者需要进行比例运算.本文将以几个小实例来介绍角度运动的相关内容 眼球转动 在很多网页中,都存在着跟随运动,比如眼球转动.鼠标在网页中移动时,眼球也会跟着朝相应方向转动 上面是眼球转动的示意图,(x0,y0)是眼球的位置,而(x,y)是鼠标的位置.设直线与垂直方向的夹角为a,假设圆心点坐标为(0,0),可以得到以下公式 tan(a)

javascript动画系列第三篇——碰撞检测

前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多,接下来使用九宫格分析法 假设黄色元素要与红色元素进行碰撞.将红色元素所处的区域分为9部分,自身处于第9部分,周围还存在8个部分.只要黄色元素进入红色元素的第9部分,就算碰撞.否则,都算未碰撞 总共分为以下5种情况: 1.处于上侧未碰撞区域——1.2.3区域 2.处于右侧未碰撞区域——3.4.5区域

深入理解javascript对象系列第三篇——神秘的属性描述符

× 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值.是否可配置.是否可修改以及是否可枚举.本文就来介绍对象中神秘的属性描述符 描述符类型 对象属性描述符的类型分为两种: 数据属性和访问器属性 数据属性 数据属性(data property)包含一个数据值的位置,在这个位置可以读取和写入值.数据属性有4个特性 [1]Configurable(可配置性

深入理解javascript作用域系列第四篇——块作用域

× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的代码,比如块作用域.随着ES6的推广,块作用域也将用得越来越广泛.本文是深入理解javascript作用域系列第四篇——块作用域 let for (var i= 0; i<10; i++) { console.log(i); } 上面这段是很熟

EnjoyingSoft之Mule ESB基础系列第三篇:Mule message structure - Mule message结构

目录 1. 探索Mule Message结构 2. Mule Message的Payload 3. Mule Message的Property 4. Mule Message的Attachment 5. Mule的Variable 6. 使用Java操作Mule Message Mule ESB是一个使用Java语言编写的开源企业服务总线,企业服务总线英文Enterprise Service Bus,简称ESB.其相关源代码也托管在GitHub上,可以在https://github.com/mu