canvas学习(十三):clip之图形剪辑

clip方法描述:

canvas本来是一个大的画布,clip方法用来从原始画布中剪切任意形状和尺寸,但是一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内而不能再访问画布上的其他区域。

 

简单实例1:圆形的探照灯

效果如图:
canvas学习(十三):clip之图形剪辑

代码如下:

var circular ={x:300,y:300,radius:150,vx:Math.random()*5+5,vy:Math.random()*5+5};
window.onload=function(){
	var myCanvas = document.getElementById("myCanvas");
	if(myCanvas.getContext("2d")){
		myCanvas.width = 600;
		myCanvas.height = 600;
		var context =myCanvas.getContext("2d");
		drawBall(context);			
	}else{
		return false;
	}
}

//该方法用来绘制图形
function drawBall(cxt){
	var canvas = cxt.canvas;
	//清空画布
	cxt.clearRect(0,0,canvas.width,canvas.height);
	
	cxt.save();

	//绘制一个与当前canvas一样大的矩形
	cxt.beginPath();
	cxt.fillStyle="#000";//黑色背景
	cxt.fillRect(0,0,canvas.width,canvas.height);
	cxt.closePath();
	
	//从原来的画布中剪辑出一个圆形
	cxt.beginPath();
	cxt.arc(circular.x,circular.y,circular.radius,0,Math.PI*2);
	cxt.fillStyle="#fff";//白色背景
	cxt.fill();
	//clip():从原始画布中剪切任意形状和尺寸。
	//一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)
	cxt.clip();
	cxt.closePath();

	//绘制内容
	cxt.font="bold 120px Arial";
	cxt.textAlign = "center";
	cxt.textBaseline = "middle";
	cxt.fillStyle = "#058";
	cxt.fillText("CANVAS",canvas.width/2,canvas.height/4);
	cxt.fillText("CANVAS",canvas.width/2,canvas.height/2);
	cxt.fillText("CANVAS",canvas.width/2,canvas.height*3/4);

	cxt.restore();
}

 

简单实例2:动态的圆形探照灯

这个实例效果与第一个实例大同小异,只是第一个是静态的,这个是动态的。所以就直接上代码吧:

var circular ={x:300,y:300,radius:150,vx:Math.random()*5+5,vy:Math.random()*5+5};
//....获取canvas对象与绘制圆形代码与上面的相同,此处就一一省略了
window.setInterval(function(){
	drawBall(context);
	update(myCanvas.width,myCanvas.height,0);
},40);
//更新圆形运动路径
function update(width,height){
	circular.x +=circular.vx;
	circular.y +=circular.vy;

	if(circular.x-circular.radius<=0){
		circular.vx = -circular.vx;
		circular.x=circular.radius;
	}

	if(circular.x+circular.radius>=width){
		circular.vx = -circular.vx;
		circular.x=width-circular.radius;
	}

	if(circular.y-circular.radius<=0){
		circular.vy = -circular.vy;
		circular.y=circular.radius;
	}

	if(circular.y+circular.radius>=height){
		circular.vy = -circular.vy;
		circular.y=height-circular.radius;
	}
}

 

简单实例3:动态的五角星探照灯(旋转角度发生变化)

 效果如图:

canvas学习(十三):clip之图形剪辑
代码如下:(获取canvas对象等代码与第一个实例相同,此处就不赘述了)

var circular ={x:300,y:300,radius:150,vx:Math.random()*5+5,vy:Math.random()*5+5};
var rot=0;
window.setInterval(function(){
	drawStar(context);
	//改变旋转角度
	update(myCanvas.width,myCanvas.height);
},40);

//绘制一个五角星的探照灯
function drawStar(cxt){		
	var canvas = cxt.canvas;
	//清空画布
	cxt.clearRect(0,0,canvas.width,canvas.height);
	
	cxt.save();

	//绘制一个与当前canvas一样大的矩形
	cxt.beginPath();
	cxt.fillStyle="#000";//黑色背景
	cxt.fillRect(0,0,canvas.width,canvas.height);
	cxt.closePath();
	
	//从原来的画布中剪辑出一个五角星
	cxt.save();
	cxt.translate(circular.x,circular.y);//设置偏移量
	cxt.rotate(rot/180*Math.PI);//设置旋转弧度
	//将每个星星的宽度和高度都缩放R倍
	cxt.scale(circular.radius,circular.radius);//使用缩放让每个星星的大小不一样(因为scale会使lineWidth随着缩放,所以此处不再设置边框的一些属性)
	drawStarPath(cxt);//绘制一个大小相同的五角星
	
	cxt.fillStyle="#fff";//白色背景
	cxt.lineJoin="round";//边角		
	//先填充,后描边
	cxt.fill();
	cxt.restore();
	cxt.clip();

	//绘制内容
	cxt.font="bold 120px Arial";
	cxt.textAlign = "center";
	cxt.textBaseline = "middle";
	cxt.fillStyle = "#058";
	cxt.fillText("CANVAS",canvas.width/2,canvas.height/4);
	cxt.fillText("CANVAS",canvas.width/2,canvas.height/2);
	cxt.fillText("CANVAS",canvas.width/2,canvas.height*3/4);

	cxt.restore();
}

/**
*该方法用来绘制一个没有偏移量的五角星的各条边
*@param cxt:canvas的上下文环境
*/
function drawStarPath(cxt){
	//绘制五角星
	cxt.beginPath();
	for(var i=0;i<5;i++){
		//绘制大圆中的五个角
		//第一个角为18度,以后大圆的每个角都是(18+72的倍数)度
		//(18+i*72)/180*Math.PI:将角度转换成弧度
		//因为绘制五角星的坐标系y轴与普通的坐标系相反,x轴以上为负数,x轴以下为正数,所以此处y轴的坐标为负数
		cxt.lineTo(Math.cos((18+i*72)/180*Math.PI),-Math.sin((18+i*72)/180*Math.PI));
		//绘制小圆中的五个角
		//与大圆的各个角一致,第一个角为54度,以后每个角都是(54+72的倍数)度
		//每个星星的小圆半径默认为大圆半径的一半
		cxt.lineTo(Math.cos((54+i*72)/180*Math.PI)*0.5,-Math.sin((54+i*72)/180*Math.PI)*0.5);
	}
	cxt.closePath();
}

//update方法与实例2中的update方法相同,只是在第一行添加代码:
rot += Math.random()*2;

 

简单实例4:动态的五角星探照灯(半径发生变化)

效果如图:
canvas学习(十三):clip之图形剪辑
 代码如下:(获取canvan对象、绘制五角星以及调用方法与实例3相同,此处就不赘述了,只写update代码)

//修改五角星的半径
function update2(width,height){
	if(circular.radius>400){
		isIncrease = false;
	}else if(circular.radius<150){
		isIncrease = true;
	}

	if(isIncrease){circular.radius +=5;}
	else{circular.radius -=5;}
}

完整代码已经上传到附件,有需要的可以下载。

最后,感谢老师的分享!