html5 canvas绘制圆形、方形矩形、线段、图片等各种图形(面向对象版本)

概念:

面向对象的方法主要是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想。总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象(万物皆对象)。

绘制圆

构造函数(将圆心位置、半径、缩放比例等参数都封装进去)

	 //构造函数
	 function Ball(o){
		this.x=0,//圆心X坐标
		this.y=0,//圆心Y坐标
		this.r=0,//半径
		this.startAngle=0,//开始角度
		this.endAngle=0,//结束角度
		this.anticlockwise=false;//顺时针,逆时针方向指定
		this.stroke=false;//是否描边
		this.fill=false;//是否填充
		this.scaleX=1;//缩放X比例
		this.scaleY=1;//缩放Y比例
		
		this.init(o);
	 }
	 //初始化
	 Ball.prototype.init=function(o){
		for(var key in o){
			this[key]=o[key];
		}
	 }

在原型上写一个绘制函数(render)

	 //绘制
	 Ball.prototype.render=function(context){
		var ctx=context;//获取上下文
		ctx.save();
		ctx.beginPath();
		ctx.translate(this.x,this.y);
		ctx.scale(this.scaleX,this.scaleY);//设定缩放
		ctx.arc(0,0,this.r,this.startAngle,this.endAngle);//画圆
		if(this.lineWidth){//线宽
			ctx.lineWidth=this.lineWidth;
		}
		if(this.fill){//是否填充
			this.fillStyle?(ctx.fillStyle=this.fillStyle):null;
			ctx.fill();
		}
		if(this.stroke){//是否描边
			this.strokeStyle?(ctx.strokeStyle=this.strokeStyle):null;
			ctx.stroke();
		}	
		ctx.restore();
	 	
	 	return this;
	 }

绘制

	var canvas = document.getElementById("canvas");
		canvas.width=300;
		canvas.height=300;
	var ctx = canvas.getContext("2d");
	var ball1 = new Ball({
		 	x:150,//圆心X坐标
			y:150,//圆心X坐标
			r:30,//半径
			startAngle:0,//开始角度
			endAngle:2*Math.PI,//结束角度
			fill:true,//是否填充
			fillStyle:'green'//填充的样式
		 }).render(ctx);//直接render

效果如下:

绘制多个圆

很方便(定义一个数组来存取小圆对象,最后一次性调用render方法绘制)

var canvas = document.getElementById("canvas");
		canvas.width=300;
		canvas.height=300;
	var ctx = canvas.getContext("2d");
	
	var renderArr=[];
	var ball,color ;
	for(var i=0;i<10;i++){
		color = '#' + Math.random().toString(16).substr(2, 6).toUpperCase();//随机颜色
		ball = new Ball({
		 	x:getRandom(40,260),//圆心X坐标
			y:getRandom(40,260),//圆心X坐标
			r:30,//半径
			startAngle:0,//开始角度
			endAngle:2*Math.PI,//结束角度
			fill:true,//是否填充
			fillStyle:color//填充的样式
		 });
		 renderArr.push(ball);//ball对象push到数组中
	}
	
	//循环数组,一次性绘制
	renderArr.forEach(function(item){
		item.render(ctx);//绘制
	})

效果如图

做动画也很方便

比如(简单做个随机运动,要做定向运动其实也是一样的道理)

	function reDraw(){
		ctx.clearRect(0,0,300,300);//清理画布
		
		//循环数组,一次性绘制
		renderArr.forEach(function(item){
			item.x=getRandom(40,260);//重新设置x
			item.y=getRandom(40,260);//重新设置y
			item.render(ctx);//绘制
		})
	}
	setInterval(reDraw,200);

效果如下

接下来要做其他的东西都可以通过类似这样的方式了,很方便

绘制方形

构造函数

function Rect(o){
		this.x=0,//x坐标
		this.y=0,//y坐标
		this.width=100,//宽
		this.height=40,//高
		this.thin=true,//线段薄一点
		
		this.init(o);
	}
	
	Rect.prototype.init=function(o){
		for(var key in o){
			this[key]=o[key];
		}
	}
	Rect.prototype.render=function(context){
		this.ctx=context;
		innerRender(this);
			
		function innerRender(obj){
			var ctx=obj.ctx;
			ctx.save()
			ctx.beginPath();
			ctx.translate(obj.x,obj.y);
			
			if(obj.lineWidth){
				ctx.lineWidth=obj.lineWidth;
			}
			if(obj.thin){
				ctx.translate(0.5,0.5);
			}
			ctx.rect(0,0,obj.width,obj.height);
			if(obj.fill){//是否填充
				obj.fillStyle?(ctx.fillStyle=obj.fillStyle):null;
				ctx.fill();
			}
			if(obj.stroke){//是否描边
				obj.strokeStyle?(ctx.strokeStyle=obj.strokeStyle):null;
				ctx.stroke();
			}	
		  	ctx.restore();
		}
	  	return this;
	}

调用示例

	var canvas = document.getElementById("canvas");
		canvas.width=300;
		canvas.height=300;
	var ctx = canvas.getContext("2d");
	var slider = new Rect({
				x:40,
				y:40,
				width:200,
				height:200,
				fill:true,
				fillStyle:'pink'
		})
		slider.render(ctx);

效果

绘制线段

构造函数

//直线的构造
	function Line(ctx,o){
		this.x=0,//x坐标
		this.y=0,//y坐标
		this.startX=0,//开始点x位置
		this.startY=0, //开始点y位置
		this.endX=0,//结束点x位置
		this.endY=0;//结束点y位置
		this.thin=false;//设置变细系数
		this.ctx=ctx;
		
		this.init(o);
	}
	Line.prototype.init=function(o){
		for(var key in o){
			this[key]=o[key];
		}
	}
	Line.prototype.render=function(){
		innerRender(this);
		
		function innerRender(obj){
			var ctx=obj.ctx;
			ctx.save()
			ctx.beginPath();
			ctx.translate(obj.x,obj.y);
			if(obj.thin){
				ctx.translate(0.5,0.5);
			}
			if(obj.lineWidth){//设定线宽
				ctx.lineWidth=obj.lineWidth;
			}
			if(obj.strokeStyle){
				ctx.strokeStyle=obj.strokeStyle;
			}
			//划线
		  	ctx.moveTo(obj.startX, obj.startY);
		  	ctx.lineTo(obj.endX, obj.endY);
		  	ctx.stroke();
		  	ctx.restore();
		}
	  	
	  	return this;
	}

调用实例

var canvas = document.getElementById("canvas");
		canvas.width=300;
		canvas.height=300;
	var ctx = canvas.getContext("2d");

	var line = new Line(ctx,{
				x:0,
				y:0,
			 	startX:10,
			 	startY:10,
			 	endX:200,
			 	endY:200,
			 	thin:true,
			 	strokeStyle:'orange'
			})
	line.render();

效果

绘制图片

构造函数

var canvas = document.getElementById("canvas");
		canvas.width=300;
		canvas.height=300;
	var ctx = canvas.getContext("2d");
	//图片对象ImageDraw构造函数
	function ImageDraw(o){
		this.id='',
		this.image=0,//图片对象(必填)
		this.sx=0,//图片切片开始x位置(显示整个图片的时候不需要填)
		this.sy=0,//图片切片开始y位置(显示整个图片的时候不需要填)
		this.sWidth=0, //图片切片开始宽度(显示整个图片的时候不需要填)
		this.sHeight=0,//图片切片开始高度(显示整个图片的时候不需要填)
		this.dx=0, //图片目标x位置(必填)
		this.dy=0, //图片目标y位置(必填)
		this.dWidth=0,//图片目标显示宽度(宽度不缩放时不必填)
		this.dHeight=0//图片目标高度高度(高度不缩放时不必填)
		
		this.init(o);
	}
	ImageDraw.prototype.init=function(o){
		for(var key in o){
			this[key]=o[key];
		}
		return this;
	}
	ImageDraw.prototype.render=function(context){
		draw(context,this);
		function draw(context,obj) {
			var ctx=context;
			ctx.save();
			
			if(!obj.image || getType(obj.dx)=='undefined' || getType(obj.dy)=='undefined'){
				throw new Error("绘制图片缺失参数");	
				return;
			} 
			ctx.translate(obj.dx,obj.dy);
			if(!getType(obj.sx)=='undefined' && getType(obj.sy)=='undefined' && obj.sWidth && obj.sHeight && obj.dWidth && obj.dHeight){
				//裁剪图片,显示时候有缩放
				ctx.drawImage(obj.image, obj.sx, obj.sy, obj.sWidth, obj.sHeight, 0, 0, obj.dWidth, obj.dHeight);
			}else if(obj.dWidth && obj.dHeight){
				ctx.drawImage(obj.image, 0, 0, obj.dWidth, obj.dHeight);//原始图片,显示时候有缩放
			}else{
				ctx.drawImage(obj.image,0, 0);//原始图片,显示时候无缩放
			}
			ctx.restore();
		}
	}
	
	var class2type={};	
	"Boolean Number String Function Array Date RegExp Object".split(" ").forEach(function(name) {
		class2type[ "[object " + name + "]" ] = name;
	});

	function getType( obj ) {
		return obj == null ?
			String( obj ) :
			class2type[ Object.prototype.toString.call(obj) ] || "undefined";
	}
	
	

绘制实例

	function draw(){
		var x=y=0,w=180,h=130;
		var img = new ImageDraw({image:image, dx:x, dy:y ,dWidth:w,dHeight:h});
		
		img.render(ctx);
	}
	
	var image = new Image();
	image.src="images/1.png";
	image.onload=function(){
		draw();
	}

效果如下:

还有其他图形就没写了,基本类似!

觉得有用的话就给个赞吧,谢谢!

猜你喜欢

转载自blog.csdn.net/dkm123456/article/details/114293618