Maison > Article > interface Web > L'effet pendule de Newton implémenté dans les compétences js_javascript
Le pendule de Newton est un appareil de démonstration de bureau inventé dans les années 1960. Cinq sphères de même masse sont fixées par des cordes suspendues et disposées étroitement les unes aux autres. Également appelée : boule pendulaire de Newton, boule pendulaire à conservation de l'élan, boule à mouvement perpétuel, boule de billard physique, boule pare-chocs, etc.
(function(window,undefined){ window.None || (window.None = {}); //重力加速度 var G=9.8; var PI=Math.PI; //帧频 var FPS=48; /* //IE角度转换 function rorateIt(node,deg){ //取得末变形前矩形的中点 var rect = node.getBoundingClientRect(), cx1 = (rect.right - rect.left) / 2, // center x cy1 = (rect.bottom - rect.top) / 2, // center y deg2rad = Math.PI / 180,//角度转弧度 rad = deg * deg2rad , cos = Math.cos(rad), sin = Math.sin(rad); var ident = "DXImageTransform.Microsoft.Matrix"; node.style.filter = "progid:"+ident +"(M11='1.0',sizingmethod='auto expand')"; //http://www.satzansatz.de/cssd/onhavinglayout.html if(!node.currentStyle.hasLayout){//在IE7中,如果没有获得hasLayout,滤镜会失效 node.style.writingMode = "tb-rl"; } var filter = node.filters.item(ident); // +-------+-------+ // | M11 | M12 | // +-------+-------+ // | M21 | M22 | // +-------+-------+ filter.M11 = cos; filter.M12 = -sin; filter.M21 = sin; filter.M22 = cos; //取得当前中心 rect = node.getBoundingClientRect(); var cx = (rect.right - rect.left) / 2; var cy = (rect.bottom - rect.top) / 2; //调整此元素的坐标系,实现CSS3 transform-origin的功能 node.style.marginLeft = cx1 - cx + "px"; node.style.marginTop = cy1 - cy + "px"; } */ //外部函数引用 //是否IE function isIE(){ return navigator.userAgent.indexOf("MSIE")>-1; } //获取当前样式 function returnStyle(obj,styleName){ var myObj = typeof obj == "string" ? document.getElementById(obj) : obj; if(document.all){ return eval("myObj.currentStyle." + styleName); } else { return eval("document.defaultView.getComputedStyle(myObj,null)." + styleName); } } //外部函数引用 //图片方法 var img=function(src){ var img=new Image(); img.src=src; return img; } //方向类,以垂直向下为0度逆时针为正 var face=function(deg,rad){ //0-360 this.unit='deg'; if(rad)deg=180/PI*deg; this.deg=deg; this.rad=PI/180*this.deg; } //矢量类 var vector=function(size,fx){ var cstrct=this.constructor; this.size=size; this.face=fx||new face(0); fx=this.face; this.toHv=function(){ var h=new cstrct(Math.sin(fx.rad)*size,90); var v=new cstrct(Math.cos(fx.rad)*size,0); return [h,v]; } } //继承,obj:需要从矢量继承的对象,arg:arguments vector.extend=function(obj,arg){ vector.apply(obj,arg); } //矢量合并方法 vector.merger=function(arrvector){ if(arguments.length>1)arrvector=arguments; var cstrct=arrvector[0].constructor; var i=0,ilav=arrvector.length; var sum=[0,0]; for(;i<ilav;i++){ var hv=arrvector[i].toHv(); sum[0]+=hv[0].size; sum[1]+=hv[1].size; } var size=Math.sqrt(sum[0]*sum[0]+sum[1]*sum[1]); var fa=new face(Math.atan(sum[0]/sum[1]),'rad'); return new cstrct(size,fa); } //力类,参数为大小和方向 var force=function(size,face){ this.unit='N'; //继承自矢量 vector.apply(this,arguments); } //加速度类 var a=function(size,face){ this.unit='m/s^2'; vector.extend(this,arguments); } //速度类 var speed=function(size,face){ this.unit='m/s'; vector.extend(this,arguments); } //刚体类,参数(body:IMG对象,m为质量) var rigid=function(body,m){ //一般情况下body为一个img对象,所以暂且只有正方形或长方形两种形式 this.body=body; this.m=m; //质量 this.focus=(this.body instanceof Image)?point(this.body.width/2,this.body.height/2):point(this.body.style.width/2,this.body.style.height/2); this.axis=point(0,0); //轴心位置(point对象) this.force=new force(0); this.a=new a(this.force.size/this.m,this.force.face); this.speed=new speed(0); //设置,可重新设置上面所有参数 this.set=function(prop,value){ this[prop]=value; } this.addForce=function(f){ return this.force=vector.merger(f,this.force); } //旋转 this.rotate=function(face,axis){ axis=axis||this.axis||this.focus; //cx1=returnStyle(this.body,"left"); //cy1=returnStyle(this.body,"left"); var rect=this.body.getBoundingClientRect(), //cx1=rect.left+axis.x, //cy1=rect.top+axis.y, cx1 = (rect.right - rect.left) / 2, cy1 = (rect.bottom - rect.top) / 2, rad=face.rad, cos = Math.cos(rad), sin = Math.sin(rad); if(isIE()){ var ident = "DXImageTransform.Microsoft.Matrix"; this.body.style.filter = "progid:"+ident +"(M11='1.0',sizingmethod='auto expand')"; if(!returnStyle(this.body,"hasLayout")){//在IE7中,如果没有获得hasLayout,滤镜会失效 this.body.style.writingMode = "tb-rl"; } var filter = this.body.filters.item(ident); filter.M11 = cos; filter.M12 = -sin; filter.M21 = sin; filter.M22 = cos; } rect = this.body.getBoundingClientRect(); //var cx=rect.left+axis.x; //var cy=rect.top+axis.y; var cx = (rect.right - rect.left) / 2; var cy = (rect.bottom - rect.top) / 2; //调整此元素的坐标系,实现CSS3 transform-origin的功能 this.body.style.left=parseInt(this.body.style.left,10) + cx1 - cx + "px"; this.body.style.top=parseInt(this.body.style.top,10) + cy1 - cy + "px"; //CSS3 var sdeg="rotate("+face.deg+"deg)"; var paxis=axis.x+"px "+axis.y+"px"; this.body.style.transformOrigin=paxis; this.body.style.MozTransformOrigin=paxis; this.body.style.WebkitTransformOrigin=paxis; this.body.style.OTransformOrigin=paxis; this.body.style.WebkitTransform=sdeg; this.body.style.MozTransform=sdeg; this.body.style.OTransform=sdeg; this.body.style.transform=sdeg; } } //刚体组合 rigid.merger=function(){ } //无弹性绳子类 var rope=function(body,length,maxForce){ this.body=body; this.length=length; this.maxForce=maxForce || Infinity || Number.MAX_VALUE; } //组合体类 var comb=function(arrObject){ } //单摆类 var pendulum=function(ripe,rigid){ } //类单摆 var likePend=function(rigid,fa,time){//刚体,初始角度,摆动频率 var self=this; this.rigid=rigid; this.body=this.rigid.body; this.axis=this.rigid.axis; this.dom=this.rigid.dom; this.m=this.rigid.m; this.rad=fa?fa.rad:fa=new face(PI/6,'rad'); //摆动 //角度30 var fx=fa.rad; //角度平方根 var m=Math.sqrt(fx); //摆动时间1秒 var atime=time||0.5; var fnum=FPS*atime; //单位增量 var fm=m/fnum; //i:角度平方根到0 var i=-m,tid; var g=new a(G); var t=1000/FPS; //o:{s:1,f:30,t:0,fun:callback} :s:(-1,1)速度增加还是减小,f:从多少度,t:到多少度,fun:摆完后运行的函数 this.swing=function(o,fun){ /* var asps=g.size*Math.cos(PI/2-fx)/(24*24*self.m); var fss=new force(asps,new face(fx-PI/2)); this.rigid.force=fss; var a=this.rigid.a; //单位时间内速度的增量 var a1=Math.acos((asps+this.rigid.speed.size)/2) this.rigid.speed=new speed(a1,new face(fx-PI/2)); a2=a1*2;*/ //{s:-1,inc:1} o=o||{s:1}; var y=-o.s*i*i+fx*o.s; if(i>=m){ self.rigid.rotate(new face(0),self.axis); clearTimeout(tid); i=-m; if(fun)fun(); return; } var f=new face(y,'rad'); self.rigid.rotate(f,axis=self.axis); i+=fm; tid=setTimeout(function(){self.swing.call(self,o,fun)},t); } this.moveTo=function(p){ self.body.style.left=p.x+"px"; self.body.style.top=p.y+"px"; } } //世界 None.world=function(param){ //param:{force:[多个force对象]} this.param=param||{}; this.config={ //全局外力 g:new a(G), className:'', width:'100%', height:'100%', left:0, top:-200, arrNav:['about','myWork','site','other','myTools'], imgW:60, imgN:5, sDeg:5, hitSound:'sounds/hit.wav', vol:0.1 } this.init(); }; None.world.prototype={ //初始化 dom:{}, init:function(){ var c=this.config; var p=this.param; //dom var dom=document.createElement("div"); dom.className=c.className; dom.style.position="absolute"; dom.style.width=p.width||c.width; dom.style.height=p.height||c.height; dom.style.left=(p.left||c.left) +"px"; dom.style.top=(p.top||c.top) +"px"; this.dom=dom; document.body.appendChild(this.dom); }, //添加一个刚体 addRigid:function(rigid,p){ if(!(rigid instanceof Array)){ rigid=[rigid]; } if(!p)p=[point(0,0)]; if(!(p instanceof Array))p=[p]; for(var i=0,rl=rigid.length;i<rl;i++){ p[i]=p[i] || p[0]; rigid[i].body.style.position="absolute"; rigid[i].body.style.left=p[i].x+"px"; rigid[i].body.style.top=p[i].y+"px"; this.dom.appendChild(rigid[i].body); } }, //添加一个外作用力 addForce:function(){ }, start:function(){ var p=this.param, c=this.config; var shit=p.hitSound||c.hitSound; var sndHit=new None.sounds(shit); sndHit.volume=p.vol||c.vol; var w=document.documentElement.offsetWidth; var imgWidth=p.imgW||c.imgW;//图片宽度 var imgNum=p.imgN||c.imgN; //图片数量 var jd=p.sDeg||c.sDeg; //最大角度 var es=p.arrNav||c.arrNav; var time=p.time||c.time; var basex=w/2-imgWidth*imgNum/2; var jiaodu=new face(jd); var rig=[],ball=[],pend=[],axis=point(imgWidth/2,0); for(var i=0,el=es.length;i<el;i++){ rig[i]=document.getElementById(es[i]); ball[i]=new rigid(rig[i],1); ball[i].set("axis",axis); pend[i]=new likePend(ball[i],jiaodu,time); } this.addRigid(pend); resize(); if(!isIE())swing(); window.onresize=resize; function hit(v){ sndHit.play(); } function swing(){ var runfun=arguments.callee; var last=pend.length-1; if(p.hitSound)hit(0); pend[0].swing({s:1},function(){ if(p.hitSound)hit(1); pend[last].swing({s:-1},runfun); }); } function resize(){ var w=document.documentElement.offsetWidth; var basex=w/2-imgWidth*imgNum/2; var n=pend.length; for(var i=0;i<n;i++){ pend[i].moveTo(point(basex+imgWidth*i,0)); } } } }; })(window);
Ce qui précède représente l’intégralité du contenu de cet article, j’espère que vous l’aimerez tous. Il peut être utile pour tout le monde d’apprendre le javascript.