首页 > 代码库 > javascript运动系列第三篇——曲线运动
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>
<iframe style="width: 100%; height: 400px;" src="http://sandbox.runjs.cn/show/rnxsu2oa" frameborder="0" width="320" height="240"></iframe>
钟摆运动
一个钟摆,一会儿朝左,一会儿朝右,周而复始,来回摆动。钟摆总是围绕着一个中心值在一定范围内作有规律的摆动,这种运动称为钟摆运动,可以把钟摆运动看做圆周运动的一部分,进而比较简单的实现钟摆运动
假设,元素初始时处于钟摆的最底点。当钟摆与竖直线夹角为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>
<iframe style="width: 100%; height: 300px;" src="http://sandbox.runjs.cn/show/nm8xgl5o" frameborder="0" width="320" height="240"></iframe>
抛物线运动
平面内到定点与定直线的距离相等的点的轨迹叫做抛物线。其中定点叫抛物线的焦点,定直线叫抛物线的准线。抛物线实际上就是一段特殊形式的曲线
抛物线方程为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 = http://www.mamicode.com/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>
<iframe style="width: 100%; height: 200px;" src="http://sandbox.runjs.cn/show/7iqvy8p5" frameborder="0" width="320" height="240"></iframe>
<script type="text/javascript">// 0){ return; } if(select[i].getBoundingClientRect().top <= 0 && select[i+1]){ if(select[i+1].getBoundingClientRect().top > 0){ change(oCon.children[i+2]) } }else{ change(oCon.children[select.length+1]) } }}document.body.onmousewheel = wheel;document.body.addEventListener(‘DOMMouseScroll‘,wheel,false);var oCon = document.getElementById("content");var close = oCon.getElementsByTagName(‘span‘)[0];close.onclick = function(){ if(this.innerHTML == ‘显示目录‘){ this.innerHTML = ‘ב; this.style.background = ‘‘; oCon.style.border = ‘2px solid #ccc‘; oCon.style.width = ‘‘; oCon.style.height = ‘‘; oCon.style.overflow = ‘‘; oCon.style.lineHeight = ‘30px‘; }else{ this.innerHTML = ‘显示目录‘; this.style.background = ‘#3399ff‘; oCon.style.border = ‘none‘; oCon.style.width = ‘60px‘; oCon.style.height = ‘30px‘; oCon.style.overflow = ‘hidden‘; oCon.style.lineHeight = ‘‘; }}for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].onmouseover = function(){ this.style.color = ‘#3399ff‘; } oCon.children[i].onmouseout = function(){ this.style.color = ‘inherit‘; if(this.mark){ this.style.color = ‘#3399ff‘; } } oCon.children[i].onclick = function(){ change(this); } }function change(_this){ for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].mark = false; oCon.children[i].style.color = ‘inherit‘; oCon.children[i].style.textDecoration = ‘none‘; oCon.children[i].style.borderColor = ‘transparent‘; } _this.mark = true; _this.style.color = ‘#3399ff‘; _this.style.textDecoration = ‘underline‘; _this.style.borderColor = ‘#2175bc‘; }// ]]></script><script type="text/javascript" src="http://files.cnblogs.com/files/xiaohuochai/contextMenu.js"></script>javascript运动系列第三篇——曲线运动