您的位置:首页 > Web前端 > HTML5

HTML5 Canvas实践(二)Canvas 高级功能

2012-09-22 18:22 267 查看
2.1 保存和恢复绘图状态

在绘制复杂canvas图像时,经常在各种样式之间切换,甚至有时候会在不同颜色之间反复切换。这种重复很麻烦,它意味着如果要返回之前使用的一些样式,必须重写大量的代码。画布能够记住一些样式和属性,这样就可以再次使用。

2.1.1 保存绘画状态

使用save方法可以保存画布状态。代码如下:

var canvas=$(“#myCanvas”);
var context = canvas.get(0).getContext(“2d”);
context.fillStyle=”rgb(255,0,0)”;
context.save(); //保存画布状态
context.fillRect(50,50,100,100); //红色正方形


2D渲染上下文会保存一个绘图状态栈,实际上是一组之前保存的状态,其中最近保存的状态位于顶部。绘图状态的默认栈是空的,调用save方法,就会有一个新状态被放入这个栈,这意味着,你完全可以多次调用save方法,将多个绘图状态逐一保存在栈中,其中最早的状态在底部。然而,无法将任何绘图状态后移,因为这个过程是有严格顺序的。



2.1.2 恢复绘图状态


现在,绘制另一个蓝色正方形,使用如下代码:

context.fillStyle=”rgb(0,0,255)”;
context.fillRect(200,50,100,100); //蓝色正方形


使用restore方法恢复原先的状态。

context.restore(); //恢复画布状态
context.fillRect(350,50,100,100); //红色正方形


效果如下:



2.2 变形

2D渲染上下文的变形功能支持的功能是非常强大的。

2.2.1 平移

将2D渲染上下文的原点从一个位置移动到另一个位置。在画布中进行平移使用translate方法,实际上它移动的是2D渲染上下文的坐标原点,而不是所绘制的对象。 通过移动2D渲染上下文的原点,画布中的所有对象都将移动相应的距离,代码如下:

context.fillRect(150,150,100,100);
context.translate(150,150);
context.fillStyle=”rgb(255,0,0)”;
context.fillRect(150,150,100,100);


效果如下所示:



一般情况下,第二次调用fillRect时,所绘制的正方形的原点坐标是(150,150),但是由于执行了一次平移,这个正方形的原点现在变成(300,300)。

2.2.2 缩放



另一个变形方法是缩放,它是调整2D渲染上下文的尺寸。它与平移的区别在于(x,y)参数是缩放倍数,而不是像素值。

context.scale(2,2);
context.fillRect(150,150,100,100);


效果如下所示:



这个例子将2D渲染上下文的x和y方向都乘以2。

2.2.3 旋转



如果想将画出的图形旋转,可以使用rotate方法。

context.rotate(0.7854); //旋转45度
context.fillRect(150,150,100,100);


结果如下图所示,这个旋转结果可能并不是所期望的:



出现这种结果,是因为rotate方法是把2D渲染上下文绕其原点(0,0)进行旋转,原点是屏幕的左上角,所绘制的正方形本身是不会旋转的,它实际上是以45度角绘制到画布中。下图可以帮助理解。



2.3 合成

本节将介绍两个全局合成属性都会影响到2D渲染上下文的绘图效果。



2.3.1 全局阿尔法值



在画布上进行绘画之前,它会应用一个与globalAlpha属性相匹配的阿尔法值。赋给globalAlpha的值必须在0.0(全透明)与1.0(不透明)之间,默认值为1.0。globalAlpha属性会影响将要绘制的对象的透明度。看下面的例子:

context.fillStyle=”rgb(63,169,245)”;
context.fillRect(50,50,100,100);
context.globalAlpha=0.5;
context.fillStyle=”rgb(255,123,172)”;
context.fillRect(100,100,100,100);


效果如下图所示:



图中,由于我们在绘制了蓝色正方形后才设置globalAlpha属性,所以只有粉色正方形才会受到阿尔法值的影响。



2.3.2 合成操作


如果一个图形叠加在另一个图形之上,2D渲染上下文会使用一个名为globalCompositeOperation属性来处理重叠,共有11种可选方法。这种合成称为源覆盖于目标之上,源是绘制的新图形,而目标是可能已经绘制了图形的2D渲染上下文。 使用下面的代码作为模板,了解这11种方法的效果。

context.fillStyle=”rgb(63,169,245)”;
context.fillRect(50,50,100,100);
context.globalCompositeOperation=”source-over”;
context.fillStyle=”rgb(255,123,172)”;
context.fillRect(100,100,100,100);


source-over

这是默认值,它表示绘制的图形(源)将画在现有画布之上。效果如下图所示:



destination-over

这个操作的值与前一个相反,目标绘制在源之上,效果如下图:



source-top

这个操作会将源绘制在目标之上,但是在重叠区上两者都是不透明的,绘制在其他位置的源是透明的。效果如下图:



destination-atop

这个操作与source-atop相反,在重叠区域上两者都是不透明的,但绘制在其他位置的目标变为透明。效果如下:



source-in

在源于目标重叠的区域只绘制源。而不重叠的部分变成透明。如下所示:



destination-in

这个操作与source-in相反,在源于目标重叠的区域保留目标。而不重叠的部分都变为透明。如下所示:



source-out

在于目标不重叠的区域上绘制源。其他部分都变成透明的。如下所示:



destination-out

在于源不重叠的区域上保留目标。其他部分都变为透明的。如下所示:



lighter

如果源于目标重叠,将两者的颜色值相加,得到的颜色值的最大值为255,结果就是白色。如下所示:



copy

只绘制源,覆盖掉目标。如下所示:



xor

只绘制出不重叠的源与目标区域。所有重叠的部分都变成透明的。如下所示:



2.4 阴影

阴影效果是被人们普遍喜欢,应用最广泛的效果,如果操作正确,它们实际上能够增加图像真实感。在画布中创建阴影效果相对较简单,它通过4个全局属性进行控制。这些属性是shadowBlur、shadowOffsetX、shadowOffsetY和shadowColor。默认情况下,2D渲染上下文是不会绘制阴影效果的。创建阴影效果的方法是将shadowColor修改为不透明值,同时将shadowBlur、shadowOffsetX、shadowOffsetY都设置为非0值。代码如下:

context.shadowBlur=20;
context.shadowColor=”rgb(0,0,0)”;
context.fillRect(50,50,100,100);


效果如下所示:



修改shadowBlur、shadowOffsetX或shadowOffsetY属性,能够创建不同的阴影效果。例如:

cotext.shadowBlur=0;
context.shadowOffsetX=10;
context.shadowOffsetY=10;
context.shadowColor="rgba(100,100,100,0.5)"
context.fillRect(200,50,100,100);


效果如下:





2.5 渐变


有时候,简单的颜色并不够用,画布的渐变颜色是一个不错的方法,fillStyle和strokeStyle都可以接受以CanvasGradient对象表示的渐变颜色值。 画布支持两种类型的渐变:线性渐变(createLinearGradient)和放射性渐变(createRadialGradient)。下面是一个基本的线性渐变的例子。

var gradient=context.createLinearGradient(0,0,0,canvas.height());
gradient.addColorStop(0,”rgb(0,0,0)”);
gradient.addColorStop(1,”rgb(255,255,255)”);
context.fillStyle=gradient;
context.fillRect(0,0,canvas.width(),canvas.height());


效果如下:



createLinearGradient方法有4个参数:渐变起点的(x,y)坐标,渐变终点的(x,y)坐标。定义一个CanvasGradient对象还不够,需要给它指定一种颜色,调用addColorStop方法,传入两个参数:颜色的偏移量(0表示渐变起点,1表示渐变终点),以及该偏移的颜色值。

2.6 将画布导出为图像

如果想将画布中绘制的图形导出为图像在其他地方使用,可以使用toDataURL方法,它能够将画布绘图转换为一个数据URL,可以通过它在浏览器上显示一个图像。看下面的例子。

context.save();
context.fillRect(50,50,100,100);
context.fillStyle=”rgb(255,0,0)”;
context.fillRect(100,100,100,100);
context.restore();
context.fillRect(150,150,100,100);
var dataURL=canvas.get(0).toDataURL();


注意,toDataURL是canvas的方法,不是2D渲染上下文的方法。dataURL中记录的值为data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t+KAAAXvElEQVR4Ae3XQQ4dNxYDwPkD3//KPZMDRItA0ovI8tINS81iG8T/fd/3H38IECBAgACBtwX++/bre3sCBAgQIEDgLwGD7jsgQIAAAQIBAgY9oEQRCBAgQICAQfcNECBAgACBAAGDHlCiCAQIECBAwKD7BggQIECAQICAQQ8oUQQCBAgQIGDQfQMECBAgQCBAwKAHlCgCAQIECBAw6L4BAgQIECAQIGDQA0oUgQABAgQIGHTfAAECBAgQCBAw6AElikCAAAECBAy6b4AAAQIECAQIGPSAEkUgQIAAAQIG3TdAgAABAgQCBAx6QIkiECBAgAABg+4bIECAAAECAQIGPaBEEQgQIECAgEH3DRAgQIAAgQABgx5QoggECBAgQMCg…。前面3个单词是data:image/png,它们表示后续内容是一个PNG格式的图像的数据URL,第4个单词是base64,表示数据采用base64编码格式,剩下的内容是以文本表示的画布图像。效果如下:



可以将dataURL变量中的字符串赋值给img作为其src,如下面的例子:

var dataURL=canvas.get(0).toDataURL();
var img=$(“<img></img>”);
img.attr(“src”,dataURL);
canvas.replaceWith(img);


现在画布上的内容是一副图像,单击右键能够出现”图片另存为…”。如下所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: