zoukankan      html  css  js  c++  java
  • 学习张鑫旭大神元素抛物线运动插件

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8">
    		<title>抛物线</title>
    		<link href="css/parabola.css" rel="stylesheet" type="text/css" />
    		<script type="text/javascript" src="js/parabola.js" ></script>
    	</head>
    	<body>
    		<div class="container" id="container"></div>
    		<div class="obj" id="obj"></div>
    		<i class="x">x轴</i>
    		<i class="y">y轴</i>
    	</body>
    </html>
    <script>
    	var container=document.getElementById("container");
    	var obj=document.getElementById("obj");
    	obj.onclick=function(){
    		funparabola(obj,container).positions().move();
    	}
    
    </script>
    

      

    function funparabola(obj,container,options){
    	//关于传参覆盖问题 涉及3个对象 defaults、options、params
    	//option是否传入判断、option与defaults求并集,option优先
    	//参数处理
    	var defaults={
    		speed:3.2,//速度 100px/s 按60帧每秒换算 每帧(100/60)px/s
    		curvature:0.001,//斜率
    		progress:function(){},
    		complete:function(){}//回调函数
    	};
    	options=options||{};
    	var params={};
    	for(var key in defaults){
    		params[key]=options[key]||defaults[key];
    	};
    	
    	//关于链式调用
    	var exports={
    		positions:function(){return this},
    		mark:function(){return this},
    		move:function(){return this},
    		init:function(){return this}
    	};
    	//css3math
    	var moveStyle="margin";
    	var testDiv=document.createElement("div");
    	var transform=[];
    	//IE9及以上区分 div元素识别oninput属性
    	if("oninput" in testDiv ){
    		//forEach函数,调用数组每个元素,并将元素传递给回调函数
    		["","ms","moz","webkit"].forEach(function (prefix){
    			transform.push(prefix + (prefix ? "T" : "t") + "ransform");
    		});
    		//alert(transform);
    		//for in语句遍历数组或者对象属性
    		for(var key in transform){
    			if(transform[key] in testDiv.style){
    				moveStyle=transform[key];
    			}
    		}
    		//alert(moveStyle);
    	}
    	//获取元素坐标
    	//定义变量
    	var a=params.curvature,b=0;
    	var objRec,containerRec,objRel,containerCenter;
    	var rate=1;
    	exports.positions=function(){
    		//通过getBoundingClientRect()方法可以获得元素元素相对于窗口位置 top/right/bottom/left 在现在浏览器中还能获取到元素宽度
    		objRec=obj.getBoundingClientRect();
    		containerRec=container.getBoundingClientRect();
    		
    		//滚动条滚动值 存在兼容性
    		//可使用jquery $(window).scrollTop()方法代替
    		var scrollLeft=document.documentElement.scrollLeft || document.body.scrollLeft;
    		var scrollTop=document.documentElement.scrollTop || document.body.scrollTop;
    		
    		//元素中心坐标
    		var objCenter={
    			//获取元素宽高:clientWidth,clientHeight
    			x: objRec.left+obj.clientWidth/2+scrollLeft,
    			y: objRec.top+obj.clientHeight/2+scrollTop
    		};
    		var containerCenter={
    			x:containerRec.left+container.clientWidth/2+scrollLeft,
    			y:containerRec.top+container.clientHeight/2+scrollTop
    		};
    		
    		//转换坐标中心 以移动对象为中心
    		objRel={
    			x:0,
    			y:0
    		};
    		containerRel={
    			x:containerCenter.x-objCenter.x,
    			y:objCenter.y-containerCenter.y
    		};
    		
    		//计算曲线 y=a*x^2+b*x+c
    		b=(containerRel.y-a*containerRel.x*containerRel.x)/containerRel.x;
    		return this;
    	}
    	
    	//移动元素
    	exports.move=function(){
    		//计算每次重绘元素x、y方向的偏移
    		//沿二次曲线运动速度是speed,那么(speed.x)²+(speed.y)²=(speed)²
    		var startx=0;
    		var tangent = 2 * a * startx + b;
    		if(containerRel.x<0){
    			rate=-1;
    		}
    		
    		var step=function(){
    			if(Math.abs(containerRel.x-startx)>2){
    				startx = startx + rate*Math.sqrt(params.speed*params.speed / (tangent * tangent + 1));
    				var x=startx,y=(a*x*x+b*x);
    				var timepath=setTimeout(step,17);
    			}else{
    				x=containerRel.x;
    				y=containerRel.y;
    			}
    			// x, y目前是坐标,需要转换成定位的像素值
    			if (moveStyle == "margin") {
    				obj.style.marginLeft = x + "px";
    				obj.style.marginTop = rate*y + "px";
    			} else {
    				obj.style[moveStyle] = "translate("+ [x + "px", rate*y + "px"].join() +")";
    			}
    		}
    		
    		step();
    		
    	}
    	//初始化方法
    	exports.init=function(){
    		this.positions();
    	}
    	
    	return exports;
    }
    

      

    *{margin:0;padding:0;}
    html,body{height:100%;}
    body{position:relative;}
    .container{position:absolute;top:200px;left:500px;100px;height:50px;border:1px solid #ccc;border-radius:20px;background:#f3f3f3;}
    .obj{position:absolute;top:400px;left:800px;30px;height:30px;border-radius:50%;background:#ccc;}
    .x{position:absolute;top:415px;left:0;100%;height:1px;background:#ccc;}
    .y{position:absolute;top:0;left:815px;1px;height:100%;background:#ccc;}
    

      

  • 相关阅读:
    eclipse里报:An internal error occurred during: "Building workspace". Java heap space
    bootstrap字体图标不显示的问题解决
    @PathVariable和@RequestParam的区别
    String Date Calendar之间的转换
    java多种方式解析json字符串
    PHP中empty、isset和is_null的使用区别
    C中atoi和strcpy的自定义实现
    【2014-08-23】Beyong Coding
    算法时间复杂度求解法【详细过程说明】
    #查找算法#【2】二叉排序树
  • 原文地址:https://www.cnblogs.com/xiaozhuzhuandxiaomoney/p/7651551.html
Copyright © 2011-2022 走看看