仿头条方形进度条

刷头条的时候看到头条的刷新进度条不错,就自己做了一个,看一下效果:

看到这个就会想到怎么去实现呢?

  1. 绘制方形(用4条线段的方式来绘制),不直接绘制方形。
  2. 控制右上角往下运动,同时右下角往上运动(改变Y左边即可)。
  3. 右边的运动完以后,停止右边,让左上角往下,左下角也往上运动。
  4. 左边运动完成后,停止左边,启动右边,重复此过程。

先来写好绘制方形的函数


	 //构造函数
	 function DynamicRectangle(o){
	 	this.x=0,//原点坐标X
	 	this.y=0,//原点坐标Y
		this.x1=0,//X1坐标
		this.y1=0,//Y1坐标
		this.x2=0,//X2坐标
		this.y2=0,//Y2坐标
		this.x3=0,//X3坐标
		this.y3=0,//Y3坐标
		this.x4=0,//X4坐标
		this.y4=0,//Y4坐标
		
		this.init(o);
	 }
	 //初始化
	 DynamicRectangle.prototype.init=function(o){
		for(var key in o){
			this[key]=o[key];
		}
	 }
	 //绘制线条
	 DynamicRectangle.prototype.drawLine=function(ctx,startX,startY,endX,endY){
	 	ctx.save();
		ctx.beginPath();
		ctx.translate(this.x,this.y);//设定原点坐标
		ctx.moveTo(startX,startY);
	 	ctx.lineTo(endX,endY);
		if(this.lineWidth){//线宽
			ctx.lineWidth=this.lineWidth;
		}
		if(this.lineCap){
			ctx.lineCap=this.lineCap;//线帽
		}
		if(this.stroke){//描边
			this.strokeStyle?(ctx.strokeStyle=this.strokeStyle):null;
			ctx.stroke();
		}	
		ctx.restore();
	 }
	 
	 //绘制
	 DynamicRectangle.prototype.render=function(context){
	 	var ctx=context;
	 	
	 	//绘制好4条线段
	 	this.drawLine(ctx,this.x1,this.y1,this.x2,this.y2);//上边线
	 	this.drawLine(ctx,this.x2,this.y2,this.x3,this.y3);//右边线
	 	this.drawLine(ctx,this.x3,this.y3,this.x4,this.y4);//下边线
	 	this.drawLine(ctx,this.x4,this.y4,this.x1,this.y1);//左边线
	 	return this;
	 }

来生成一个方形

		//创建方形
		var rect = new DynamicRectangle({
			x:7,//原点坐标x
			y:2,//原点坐标y
		 	x1:0,//方形左上角坐标x
			y1:0,//方形左上角坐标y
			x2:100,//方形右上角坐标x
			y2:0,//方形右上角坐标y
			x3:100,//方形右下角坐标x
			y3:60,//方形右下角坐标y
			x4:0,//方形左下角坐标x
			y4:60,//方形左下角坐标y
			lineWidth:1.5,//线宽
			lineCap:'square',//线帽
			stroke:true,//描边
			strokeStyle:'palevioletred',//线的颜色
		 }).render(ctx);

效果如下:

 

如何动起来呢,先来看右边,要做到右上角往下运动,只要使右上角的Y坐标增加就可以,加入定时函数,重复的去增加右上角的Y坐标,再重新绘制出来

         var dir=1;//方向
         var dis=2;//X轴移动初始值		
         move=function(){
	        //清理画布
		 	ctx.clearRect(0,0,W,H);
		 	
		 	rect.y2+=dis*dir;
		 	rect.render(ctx);	
	
		 }
		 timmer=setInterval(move,10);//开始任务

此时的效果是这样的

但是会一直往下走,所以要限定方向,到达底部后折返往上,并且回到顶部后再次调整方向往下,在move函数里面调整一下即可:

		 move=function(){
		 	//清理画布
		 	ctx.clearRect(0,0,W,H);
		 	
		 	rect.y2+=dis*dir;
		 	rect.render(ctx);	
	
			if(rect.y2>=60||rect.y2<=0){
				dir=-dir;//改变方向
			}
		 }

加入右下角的运动

	 move=function(){
		 	//清理画布
		 	ctx.clearRect(0,0,W,H);
		 	
		 	rect.y2+=dis*dir;
		 	rect.y3+=-dis*dir;
		 	rect.render(ctx);	
	
			if(rect.y2>=60||rect.y2<=0||rect.y3>=60||rect.y3<=0){
				dir=-dir;//改变方向
			}
		 }

再把左边加入运动,因为右边运动完后切换到左边,左边运动完停止,右边再运动,需要加入一个参数来控制。

	 move=function(){
		 	//清理画布
		 	ctx.clearRect(0,0,W,H);
		 	
		 	if(animateDir=='right'){//长方形的右边在运动
		 		rect.y2+=dis*dir;
		 		rect.y3+=-dis*dir;
		 	}else{//长方形的左边在运动
		 		rect.y1+=dis*dir2;
		 		rect.y4+=-dis*dir2;
		 	}
		 	rect.render(ctx);
		 	if(animateDir=='right'){
		 		if(rect.y2>=60||rect.y2<=0||rect.y3>=60||rect.y3<=0){
			 		dir=-dir;
			 		animateDir='left';//切换为左边运动
			 	}
		 	}else{
		 		if(rect.y1>=60||rect.y1<=0||rect.y4>=60||rect.y4<=0){
			 		dir2=-dir2;
			 		animateDir='right';//切换为右边运动
			 	}
		 	}
	
		 }

此时效果如下:

加快一下速度,timmer=setInterval(move,10);

把这些都封装一下,再看一下效果

完整代码:

<!DOCTYPE html>
<html>
	<head lang="en">
		<meta charset="GBK">
		<title></title>
		<style>
*{
    margin: 0;
    padding: 0;
}

</style>
	</head>
	<body>
		<button onclick='start()'>开始</button>
		<button onclick='stop()'>结束</button>
		
		<div id='process'>
		</div>
		
	<script type="text/javascript">
	
	var timmer=null;
	function start(){
		if(timmer) return ;//防止重复点击
		var process = document.getElementById('canvasDiv');
		process.style.display="block";
		timmer=setInterval(move,10);//开始任务
	}
	function stop(){
		var process = document.getElementById('canvasDiv');
		process.style.display="none";
		clearInterval(timmer); //结束任务
		timmer=null;
	}
	
	 //构造函数
	 function DynamicRectangle(o){
	 	this.x=0,//原点坐标X
	 	this.y=0,//原点坐标Y
		this.x1=0,//X1坐标
		this.y1=0,//Y1坐标
		this.x2=0,//X2坐标
		this.y2=0,//Y2坐标
		this.x3=0,//X3坐标
		this.y3=0,//Y3坐标
		this.x4=0,//X4坐标
		this.y4=0,//Y4坐标
		this.order=0,
		this.init(o);
	 }
	 //初始化
	 DynamicRectangle.prototype.init=function(o){
		for(var key in o){
			this[key]=o[key];
		}
	 }
	 //绘制线条
	 DynamicRectangle.prototype.drawLine=function(ctx,startX,startY,endX,endY){
	 	ctx.save();
		ctx.beginPath();
		ctx.translate(this.x,this.y);//设定原点坐标
		ctx.moveTo(startX,startY);
	 	ctx.lineTo(endX,endY);
		if(this.lineWidth){//线宽
			ctx.lineWidth=this.lineWidth;
		}
		if(this.lineCap){
			ctx.lineCap=this.lineCap;//线帽
		}
		if(this.stroke){//描边
			this.strokeStyle?(ctx.strokeStyle=this.strokeStyle):null;
			ctx.stroke();
		}	
		ctx.restore();

	 }
	 
	 //绘制
	 DynamicRectangle.prototype.render=function(context){
	 	var ctx=context;
	 	
	 	//绘制好4条线段
	 	this.drawLine(ctx,this.x2,this.y2,this.x3,this.y3);//右边线
	 	this.drawLine(ctx,this.x4,this.y4,this.x1,this.y1);//左边线
	 	if(this.order>0){//先绘制上面那条边
	 		this.drawLine(ctx,this.x1,this.y1,this.x2,this.y2);//上边线
			this.drawLine(ctx,this.x3,this.y3,this.x4,this.y4);//下边线
	 	}else{先绘制下面那条边
			this.drawLine(ctx,this.x3,this.y3,this.x4,this.y4);//下边线
			this.drawLine(ctx,this.x1,this.y1,this.x2,this.y2);//上边线
	 	}
	 	return this;
	 }
	
		 
	createCanvas();
	
	var move;
	function createCanvas(){
		var process = document.getElementById('process');
		var div = document.createElement('div');
		div.id="canvasDiv";
		div.style.cssText="position:absolute;top:50px;left:30px;display:none;";
	
		var canvas = document.createElement('canvas');
		var W = canvas.width = 114;
		var H = canvas.height = 64;
		
		div.appendChild(canvas);
		process.appendChild(div);
		
		var ctx = canvas.getContext('2d');
		
		//创建方形
		var rect = new DynamicRectangle({
			x:7,//原点坐标x
			y:2,//原点坐标y
		 	x1:0,//方形左上角坐标x
			y1:0,//方形左上角坐标y
			x2:100,//方形右上角坐标x
			y2:0,//方形右上角坐标y
			x3:100,//方形右下角坐标x
			y3:60,//方形右下角坐标y
			x4:0,//方形左下角坐标x
			y4:60,//方形左下角坐标y
			lineWidth:1.5,//线宽
			lineCap:'square',//线帽
			stroke:true,//描边
			strokeStyle:'palevioletred',//线的颜色
			order:1//绘制顺序
		 }).render(ctx);
		 
		 var dir=1;//方向
		 var dir2=1;//方向2
		 var dis=2;//X轴移动初始值
		 var animateDir='right';
		 
		 move=function(){
		 	//清理画布
		 	ctx.clearRect(0,0,W,H);
		 	
		 	if(animateDir=='right'){
		 		rect.y2+=dis*dir;
		 		rect.y3+=-dis*dir;
		 	}else{
		 		rect.y1+=dis*dir2;
		 		rect.y4+=-dis*dir2;
		 	}
		 	rect.render(ctx);
		 	if(animateDir=='right'){
		 		if(rect.y2>=60||rect.y2<=0||rect.y3>=60||rect.y3<=0){
			 		dir=-dir;
			 		animateDir='left';
			 		if(dir<0){
			 			rect.order=-1;
			 		}else{
			 			rect.order=1;
			 		}
			 	}
		 	}else{
		 		if(rect.y1>=60||rect.y1<=0||rect.y4>=60||rect.y4<=0){
			 		dir2=-dir2;
			 		animateDir='right';
			 		if(dir2<0){
			 			rect.order=-1;
			 		}else{
			 			rect.order=1;
			 		}
			 	}
		 	}
	
		 }
		 
	}
</script>
	</body>
</html>

稍作改造就可以用起来,给个三连吧兄弟们!