你的位置:首页 > Java教程

[Java教程]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" >  <div id="test" ></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" >  <div id="test" ></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>