HTML5 Canvas实践(二)Canvas 高级功能
2012-09-22 18:22
267 查看
2.1 保存和恢复绘图状态
在绘制复杂canvas图像时,经常在各种样式之间切换,甚至有时候会在不同颜色之间反复切换。这种重复很麻烦,它意味着如果要返回之前使用的一些样式,必须重写大量的代码。画布能够记住一些样式和属性,这样就可以再次使用。
2.1.1 保存绘画状态
使用save方法可以保存画布状态。代码如下:
2D渲染上下文会保存一个绘图状态栈,实际上是一组之前保存的状态,其中最近保存的状态位于顶部。绘图状态的默认栈是空的,调用save方法,就会有一个新状态被放入这个栈,这意味着,你完全可以多次调用save方法,将多个绘图状态逐一保存在栈中,其中最早的状态在底部。然而,无法将任何绘图状态后移,因为这个过程是有严格顺序的。
2.1.2 恢复绘图状态
现在,绘制另一个蓝色正方形,使用如下代码:
使用restore方法恢复原先的状态。
效果如下:
2.2 变形
2D渲染上下文的变形功能支持的功能是非常强大的。
2.2.1 平移
将2D渲染上下文的原点从一个位置移动到另一个位置。在画布中进行平移使用translate方法,实际上它移动的是2D渲染上下文的坐标原点,而不是所绘制的对象。 通过移动2D渲染上下文的原点,画布中的所有对象都将移动相应的距离,代码如下:
效果如下所示:
一般情况下,第二次调用fillRect时,所绘制的正方形的原点坐标是(150,150),但是由于执行了一次平移,这个正方形的原点现在变成(300,300)。
2.2.2 缩放
另一个变形方法是缩放,它是调整2D渲染上下文的尺寸。它与平移的区别在于(x,y)参数是缩放倍数,而不是像素值。
效果如下所示:
这个例子将2D渲染上下文的x和y方向都乘以2。
2.2.3 旋转
如果想将画出的图形旋转,可以使用rotate方法。
结果如下图所示,这个旋转结果可能并不是所期望的:
出现这种结果,是因为rotate方法是把2D渲染上下文绕其原点(0,0)进行旋转,原点是屏幕的左上角,所绘制的正方形本身是不会旋转的,它实际上是以45度角绘制到画布中。下图可以帮助理解。
2.3 合成
本节将介绍两个全局合成属性都会影响到2D渲染上下文的绘图效果。
2.3.1 全局阿尔法值
在画布上进行绘画之前,它会应用一个与globalAlpha属性相匹配的阿尔法值。赋给globalAlpha的值必须在0.0(全透明)与1.0(不透明)之间,默认值为1.0。globalAlpha属性会影响将要绘制的对象的透明度。看下面的例子:
效果如下图所示:
图中,由于我们在绘制了蓝色正方形后才设置globalAlpha属性,所以只有粉色正方形才会受到阿尔法值的影响。
2.3.2 合成操作
如果一个图形叠加在另一个图形之上,2D渲染上下文会使用一个名为globalCompositeOperation属性来处理重叠,共有11种可选方法。这种合成称为源覆盖于目标之上,源是绘制的新图形,而目标是可能已经绘制了图形的2D渲染上下文。 使用下面的代码作为模板,了解这11种方法的效果。
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值。代码如下:
效果如下所示:
修改shadowBlur、shadowOffsetX或shadowOffsetY属性,能够创建不同的阴影效果。例如:
效果如下:
2.5 渐变
有时候,简单的颜色并不够用,画布的渐变颜色是一个不错的方法,fillStyle和strokeStyle都可以接受以CanvasGradient对象表示的渐变颜色值。 画布支持两种类型的渐变:线性渐变(createLinearGradient)和放射性渐变(createRadialGradient)。下面是一个基本的线性渐变的例子。
效果如下:
createLinearGradient方法有4个参数:渐变起点的(x,y)坐标,渐变终点的(x,y)坐标。定义一个CanvasGradient对象还不够,需要给它指定一种颜色,调用addColorStop方法,传入两个参数:颜色的偏移量(0表示渐变起点,1表示渐变终点),以及该偏移的颜色值。
2.6 将画布导出为图像
如果想将画布中绘制的图形导出为图像在其他地方使用,可以使用toDataURL方法,它能够将画布绘图转换为一个数据URL,可以通过它在浏览器上显示一个图像。看下面的例子。
注意,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,如下面的例子:
现在画布上的内容是一副图像,单击右键能够出现”图片另存为…”。如下所示:
在绘制复杂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);
现在画布上的内容是一副图像,单击右键能够出现”图片另存为…”。如下所示:
相关文章推荐
- HTML5 canvas游戏开发实战 3 : canvas高级功能
- HTML5 Canvas游戏开发(二)高级功能
- 高级UI-Canvas 使用,Canvas 实践 自定义Drawable
- vSphere高级功能(二)—— 分布式资源调度功能DRS实践
- html5之canvas画图 1.写字板功能
- javascript HTML5 Canvas实现圆盘抽奖功能
- html5 canvas画图实践
- 让IE8支持HTML5及canvas功能!chart.js图表绘制工具库IE8上兼容方案
- javascript HTML5 Canvas实现圆盘抽奖功能
- 让IE8支持HTML5及canvas功能!
- 让IE8支持HTML5及canvas功能!
- Html5之高级-6 HTML5 Canvas绘图(Canvas概述、Canvas绘图、处理 Canvas 中的图像)
- canvas与html5实现视频截图功能
- 基于HTML5 画布功能canvas的绘画板:画线、画圆、画矩形、橡皮、改变线条
- HTML5新特性 canvas 实践
- canvas与html5实现视频截图功能
- 【知识整理】利用html5 canvas技术实现反差式对焦功能的相关探讨
- 玩转 html5 (二) ---- 用 canvas 结合脚本在画布上画简单的图 (html5 又一强大功能)
- 7.HTML5 高级Canvas技术-1
- html5开发手机打电话发短信功能,html5的高级开发,html5开发大全,html手机电话短信功能详解