微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于HTML5的绘图——绘制变形图形

用户在绘制图形时常常需要对图形进行操作,如平移图形、缩放图形、扩大图形以及旋转图形等,HTML5提供了对图形变换处理功能(如变换坐标和变换矩阵)

保存和恢复状态及输出图像

保存和恢复状态

save()函数和restore()函数都是用来保存和恢复绘画状态的,不需要传递任何参数,绘画状态就是指坐标原点、变形时的变化矩阵、以及上下文对象的当前属性值等内容

保存和恢复当前状态时首先调用save()函数将当前状态保存到栈中,在完成设置的操作后再调用restore()函数从栈中取出之前保存的图形上下文状态进行恢复,通过这种方法可以对之后绘制的图形取消裁剪区域

保存和恢复状态可以用到以下区域:

1、当前用到的变形,即移动、旋转和缩放等

2、图像裁剪

3、改变图形上下文的以下属性值时:strokeStyle,fillStyle,globalAlpha,linewidth,lineCap,lineJoin,miterLimit,shadowOffsetX,shadowOffsetY,shadowBlur,shadowColor,globalCompositeOperation

下面通过一个案例解释save()和restore()函数的使用:

(1)添加新的HTML页面页面合适位置添加新的canvas元素

<canvas id="canvas" width="250px" height="250px" style="margin-left:100px;"></canvas>

(2)页面加载时调用javascript脚本

function GetContext(id){
	var canvas = document.getElementById(id);
	if(canvas && canvas.getContext){
		var context = canvas.getContext("2d");
		return context;
	}
}
function draw(){
	var ctx = GetContext("canvas");
	ctx.fillStyle = "#FF97CB";
	ctx.fillRect(0,250,250);//最外层矩形
	ctx.save();//保存状态
	ctx.fillStyle = "blue";
	ctx.fillRect(15,15,220,220);//绘制一个内部矩形
	ctx.save();//保存状态
	ctx.fillStyle = "green";//设置新的填充颜色
	ctx.fillRect(30,30,190,190);
	ctx.restore();//恢复状态
	ctx.fillRect(45,45,160,160);
	ctx.restore();//恢复状态
	ctx.fillRect(60,60,130,130);
}
window.addEventListener("load",draw,true);

(3)运行结果如下所示


输出图像

在画布上完成一副图形或图像后常常需要对绘制的作品进行保存和输出等,使用canvas API就可以完成该功能

canvas API保存和输出文件的原理是把当前的绘画状态输出一个dataURL地址所指向的数据中的过程。而dataURL是指目前大多数浏览器能够识别的一种base64位编码的URL,主要用于小型的、可以在网页中直接嵌入而不需要外部文件嵌入的数据,如img元素中的图像文件等。

保存和输出图像需要调用toDataURL()函数,该函数可以把绘制状态输出一个dataURL中,然后重新加载客户端可直接把装载后的文件进行保存。该函数语法如下所示:

canvas.toDataURL(type);
函数中参数type,表示要输入数据的MIME类型

下面通过一个示例介绍toDataURL()函数的使用;

(1)添加新的HTML页面页面合适位置添加canvas元素和input元素

<canvas id="canvas" width="260px" height="260px" style="margin-left:200px;"></canvas>
<input type="button" value="输出图像" onclick="javascript:ShowImg();" />
<img id="img1" width="150px" height="150px" />

(2)页面加载时调用javascript脚本,运行draw()函数,点击按钮时调用ShowImg()函数

function GetContext(id){
	var canvas = document.getElementById(id);
	if(canvas && canvas.getContext){
		var context = canvas.getContext("2d");
		return context;
	}
}
function draw(){
	var ctx = GetContext("canvas");
	ctx.fillStyle = "yellow";
	ctx.fillRect(5,5,250);
	ctx.beginPath();
	ctx.arc(150,150,80,(Math.PI*2)/4,true);
	ctx.strokeStyle="blue";
	ctx.stroke();
}
function ShowImg(){
	var img1 = document.getElementById("canvas").toDataURL("images/jpeg");
	document.getElementById("img1").src=img1;
}

window.addEventListener("load",true);

(3)运行结果如下所示:


坐标变换

HTML5绘制图形时是以坐标点为基准来进行绘制的,认情况下画布的左上角对应于坐标轴的原点。如果对这个坐标轴进行改变,就可以实现图形的变化处理了。HTML5中对坐标的变换处理有3种方式,具体说明如下所示:

(1)平移

绘制平移图形主要是通过translate()函数来实现的,该函数语法格式如下所示:

context.translate(x,y);
translate()函数包含两个参数:x表示将坐标原点向右移动若干个单位,认情况下以像素为单位;y表示将坐标原点向下移动若干个单位,认情况下以像素为单位

(2)缩放

绘制缩放图形时需要调用scale()函数,该函数语法格式如下所示:

context.scale(x,y);
scale()函数包含两个参数:x表示水平方向的放大倍数;y表示垂直方向的放大倍数。如果要实现图形缩小的效果,设置参数x和y为0~1之间的小数即可,如0.5表示缩小一半

(3)旋转

绘制旋转图形需要调用rotate()函数,该函数语法格式如下所示:

context.rotate(angle);
rotate()函数只有一个参数angle,该参数表示旋转的角度,旋转的中心点是坐标原点。旋转是按照顺时针方向进行的,如果要实现逆时针旋转,将angle值设置为负值即可

下面通过一个示例介绍图形变换基本应用:

(1)添加新的HTML页面页面合适位置田间canvas元素

<canvas id="canvas" width="360px" height="300px" style="margin-left:300px;"></canvas>	

(2)页面加载时运行javascript代码,绘制

function GetContext(id){
	var canvas = document.getElementById(id);
	if(canvas && canvas.getContext){
		var context = canvas.getContext("2d");
		return context;
	}
}
function draw(){
	var ctx = GetContext("canvas");
	ctx.translate(130,120);
	for(var i=1;i<7;i++){
		ctx.save();
		//ctx.fillStyle="rgba('+(30*i)+','+(255-30*i)+',255,1.0)";
		for(var j=0;j<i*7;j++){
			ctx.translate(1,1);
			ctx.rotate(Math.PI*2/(i*7));
			ctx.beginPath();
			ctx.arc(0,i*12,Math.PI*2,false);
			ctx.fill();
		}
		ctx.restore();
	}
}

window.addEventListener("load",true);

(3)运行结果如下所示


矩阵变换

当使用坐标变换不能满足条件时,可以使用另一种比较复杂的技术——变换矩阵

介绍矩阵变换之前首先来介绍下变换矩阵,矩阵是专门用来实现图形变形的,它与坐标一起配合使用达到变形的目的。当图形上下文被创建完毕时,事实上也创建了一个认的变换矩阵,如果不对这个矩阵进行修改,那么接下来绘制的图形都会以画布的左上角为坐标原点进行绘制图形。绘制出来的图形不经过缩放变形处理,但是如果对这个变换矩阵进行修改,那么情况就不一样了。

使用上下文对象的transform()函数可以实现变换矩阵,该函数语法格式如下所示:

context.transform(ma1,ma2,mb1,mb2,dx,dy);
上述语法中ma1、ma2、mb1和mb2用来修改使用这个方法后绘制图形的计算方法,从而达到变形的目的。dx和dy用来移动坐标原点,dx表示将坐标原点在x轴上向右移动x个单位,dy表示将坐标原点在y轴上向下移动y个单位。认情况下dx和dy都是以像素为单位。

坐标变换中的三种函数实际上都隐式地修改了变换矩阵,他们可以使用transform()函数来代替,具体说明如下所示:

translate(x,y)

可以使用transform(1,1,x,y)或者transform(0,y)函数进行替代,前面四个参数表示不对图形进行操作,将dx设为x表示将坐标原点向右移动x个单位,dy设置为y表示坐标原点向下移动y个单位

scale(x,y)

可以使用transform(x,y,0)或者transform(0,0)函数进行替代,前面四个参数表示将图形横向扩大或缩小x倍,纵向扩大或缩小y倍,dx和dy表示坐标原点不变

rotate(x,y)替换方法如下所示:

transform(Math.cos(angle*Math.PI/180),

                      Math.sin(angle*Math.PI/180),

                      -Math.sin(angle*Math.PI/180),

                      Math.cos(angle*MathPI/180),

                      0,0)

或者

transform( -Math.sin(angle*Math.PI/180),

                      Math.cos(angle*Math.PI/180),

                      Math.sin(angle*MathPI/180),

                      0,0)

上述代码中前四个参数以三角函数的形式表示出来,共同完成图形按照angle角度的顺时针旋转处理,dx和dy为0表示不移动坐标原点。

使用transform()函数后,要绘制的图形都会按照移动后的坐标原点与新的变换矩阵相结合的方法进行重置,必要时可以使用setTransform()函数将变换矩阵进行重置,该函数语法格式如下所示:

context.setTransform(ma1,dy);
上述语法中参数的用法与transform()函数相同,实际上该函数的作用是将画布上的最左上角重置为坐标原点,当图形上下文创建完毕时将所创建的初始变换矩阵设置为当前变换矩阵,然后使用transform()函数

下面通过一个示例演示transform()函数的使用:

(1)添加新的HTML页面,在页面合适位置添加canvas元素

<canvas id="canvas" style="margin-left:300px;" width="300px" height="300px"></canvas>

(2)页面加载时运行javascript代码绘制图形

function GetContext(id){
	var canvas = document.getElementById(id);
	if(canvas && canvas.getContext){
		var context = canvas.getContext("2d");
		return context;
	}
}
function draw(){
	var context = GetContext("canvas");
	context.transform(1,150);
	context.beginPath();
	context.fillStyle="rgba(255,0.25)";
	rad=18*Math.PI/90;
	for(i=0;i<10;i++){
		context.fillRect(0,100,100);
		context.transform(Math.cos(rad),Math.sin(rad),-Math.sin(rad),Math.cos(rad),0);
		context.closePath();
	}
}

window.addEventListener("load",true);

(3)运行结果如下所示

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。