js实现的牛顿摆效果


Posted in Javascript onMarch 31, 2015

牛顿摆是一个1960年代发明的桌面演示装置,五个质量相同的球体由吊绳固定,彼此紧密排列。又叫:牛顿摆球、动量守恒摆球、永动球、物理撞球、碰碰球等。

(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);

以上所述就是本文的全部内容了,希望大家能够喜欢。能够对大家学习javascript有所帮助。

Javascript 相关文章推荐
javascript parseInt 函数分析(转)
Mar 21 Javascript
javascript 面向对象继承
Nov 26 Javascript
一行代码告别document.getElementById
Jun 01 Javascript
document.createElement()用法及注意事项(ff下不兼容)
Mar 13 Javascript
JS中获取数据库中的值的方法
Jul 14 Javascript
JavaScript实现向右伸出的多级网页菜单效果
Aug 25 Javascript
JavaScript检查子字符串是否在字符串中的方法
Feb 03 Javascript
使用JavaScript实现ajax的实例代码
May 11 Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 Javascript
关于axios如何全局注册浅析
Jan 14 Javascript
js/jQuery实现全选效果
Jun 17 jQuery
JS实现音量控制拖动
Jan 15 Javascript
JS动态显示表格上下frame的方法
Mar 31 #Javascript
JS实现控制表格只显示行边框或者只显示列边框的方法
Mar 31 #Javascript
jQuery选择器源码解读(八):addCombinator函数
Mar 31 #Javascript
JS显示表格内指定行html代码的方法
Mar 31 #Javascript
jQuery选择器源码解读(七):elementMatcher函数
Mar 31 #Javascript
jQuery选择器源码解读(六):Sizzle选择器匹配逻辑分析
Mar 31 #Javascript
jQuery选择器源码解读(五):tokenize的解析过程
Mar 31 #Javascript
You might like
php preg_match_all结合str_replace替换内容中所有img
2008/10/11 PHP
使用VisualStudio开发php的图文设置方法
2010/08/21 PHP
详解Window7 下开发php扩展
2015/12/31 PHP
Android AsyncTack 异步任务实例详解
2016/11/02 PHP
使用laravel根据用户类型来显示或隐藏字段
2019/10/17 PHP
JS获取scrollHeight问题想到的标准问题
2007/05/27 Javascript
IE中radio 或checkbox的checked属性初始状态下不能选中显示问题
2009/07/25 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
2013/04/28 Javascript
简单的两种Extjs formpanel加载数据的方式
2013/11/09 Javascript
JS 去除Array中的null值示例代码
2013/11/20 Javascript
JQuery中的html()、text()、val()区别示例介绍
2014/09/01 Javascript
node.js中的url.parse方法使用说明
2014/12/10 Javascript
js实现文字截断功能
2016/09/14 Javascript
jQuery实现标签页效果实战(4)
2017/02/08 Javascript
用angular实现多选按钮的全选与反选实例代码
2017/05/23 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
JavaScript调用模式与this关键字绑定的关系
2018/04/21 Javascript
详解VScode编辑器vue环境搭建所遇问题解决方案
2019/04/26 Javascript
使用next.js开发网址缩短服务的方法
2020/06/17 Javascript
[14:20]刀塔大凶女神互压各路奇葩屌丝
2014/05/16 DOTA
Python判断文件和文件夹是否存在的方法
2015/05/21 Python
每天迁移MySQL历史数据到历史库Python脚本
2018/04/13 Python
python中Array和DataFrame相互转换的实例讲解
2021/02/03 Python
CSS3使用transition属性实现过渡效果
2018/04/18 HTML / CSS
HTML5 canvas基本绘图之绘制五角星
2016/06/27 HTML / CSS
美国家居装饰网上商店:Lulu & Georgia
2019/09/14 全球购物
Piercing Pagoda官网:耳环、戒指、项链、手链等
2020/09/28 全球购物
上班迟到检讨书
2014/01/10 职场文书
农民致富事迹材料
2014/01/23 职场文书
采购类个人求职的自我评价
2014/02/18 职场文书
应届生求职信
2014/05/31 职场文书
超市理货员岗位职责
2014/07/04 职场文书
机电一体化专业求职信
2014/07/22 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
平凡的世界读书笔记
2015/06/25 职场文书
三八妇女节新闻稿
2015/07/17 职场文书