概念:
面向对象的方法主要是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想。总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象(万物皆对象)。
绘制圆
构造函数(将圆心位置、半径、缩放比例等参数都封装进去)
//构造函数
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();
}
效果如下:
扫描二维码关注公众号,回复:
12739481 查看本文章
还有其他图形就没写了,基本类似!