HTML5- Canvas入门(七)
这是本系列的最后一篇入门文章,主要是对剩余的未说明的canvas方法来逐个介绍。
首先,如果你是一名擅长矢量设计的设计师,对Illustrator或者Fireworks很熟悉的话,那你肯定知道它们有一个很强大的矢量混合处理功能,可以对多个矢量路径进行“合并”、“拆分”、“结合”、“相交”等系列操作。 如下图,在Fireworks中有三个矢量路径,我先把灰色的圆形和粉红色的矩形进行了“结合路径”的处理,接着又把结合后的路径跟绿色的星形矢量进行了“合并路径”操作:
在canvas中也有实现同样功能的属性—— globalCompositeOperation,利用它,可以实现对画布上已有的图像(暂称为“目标图像”)和新绘制的图像(暂成为“源图像”)来执行相关的混合处理。
globalCompositeOperation的可取值见下表:
值 | 描述 |
---|---|
source-over | 默认。在目标图像上显示源图像。 |
source-atop | 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。 |
source-in | 在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。 |
source-out | 在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。 |
destination-over | 在源图像上方显示目标图像。 |
destination-atop | 在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。 |
destination-in | 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。 |
destination-out | 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。 |
lighter | 显示源图像 + 目标图像。 |
copy | 显示源图像。忽略目标图像。 |
xor | 使用异或操作,对源图像与目标图像进行结合处理。 |
我们绘制一个蓝色的圆形和一个粉红色的矩形,对它们进行类似上图“结合路径”(xor)的处理:
<canvas id="myCanvas" width="300" height="200" style="border:solid 1px #CCC;">
您的浏览器不支持canvas,建议使用最新版的Chrome
</canvas> <script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.arc( 80, 80, 40, 0, 2*Math.PI);
ctx.fillStyle = "#4DA6FF";
ctx.fill();
ctx.fillStyle = "#FF7373";
ctx.globalCompositeOperation="xor"; //异或结合处理
ctx.fillRect(95,50,100,90);
</script>
效果如下:
各globalCompositeOperation 属性值的最终效果可以参考下图(蓝色矩形为目标图像,红色圆形为后续新绘制的源图像):
接着介绍 isPointInPath() 方法,它接受一个指定点的坐标值作为参数,可判断该指定点是否位于当前路径内,并返回对应的Boolean值。
我们来绘制一个矩形,然后判断点(115, 70)是否位于该矩形路径内部,如果是,则填充该矩形,否则alert出相关信息:
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.rect(95,50,100,90);
if (ctx.isPointInPath(115,70)){ //判断点(115,70)是否位于当前路径内
ctx.fillStyle = "#FF7373";
ctx.fill();
}else{
alert("不在矩形路径内");
}
</script>
由于该点是位于矩形路径上的,故成功绘制矩形,而不会弹窗:
我们常规使用canvas绘制多个图片的时候,总有一些会重复使用到的状态,比如我们先绘制了一个“倾斜20度、填充颜色为红色”的矩形,接着绘制了一个“不倾斜、填充颜色为蓝色”的矩形。如果后面我们又要重复绘制一个“倾斜20度、填充颜色为红色”的矩形,又得重新设置画布的setTransform和fillStyle值,自然是挺烦人的事情。
canvas的 save() 和 restore() 方法便能为我们处理这个问题——使用 .save() 方法能为我们保存当前画布的状态,使用 .restore() 方法可以把当前画布状态返回到上一次保存的状态,有点类似于我们玩游戏过程中存档和读档的功能。
我们先说说canvas的“状态”,它指的是像我们上面提到的“倾斜(变形)、填充”这样的配置,是当前所有样式和变形的一个快照。我们可以保存和读取到的状态包括:
当前的 transformation matrix;
当前的 clipping region;
当前的属性值:fillStyle, font, globalAlpha,
globalCompositeOperation, lineCap, lineJoin,
lineWidth, miterLimit, shadowBlur, shadowColor,
shadowOffsetX, shadowOffsetY, strokeStyle, textAlign,
textBaseline
canvas的状态是以栈(stack)的方式保存的,遵循先进后出(FILO)原则。每一次调用 save 方法,当前的状态就会被推入栈中保存起来;当调用 restore 方法时,最新入栈的状态则被推出使用。
我们来一个简单的例子:
<canvas id="myCanvas" width="150" height="150" style="border:solid 1px #CCC;">
您的浏览器不支持canvas,建议使用最新版的Chrome
</canvas> <script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(20,20,100,100);
ctx.save(); //保存状态(fillStyle = "green")
ctx.fillStyle = "red";
ctx.fillRect(40,40,60,60);
ctx.restore(); //读取上次保存的状态(fillStyle = "green")
ctx.fillRect(60,60,20,20); //填充了绿色的矩形而非红色的
</script>
效果如下:
上面的例子很好理解,不过为了了解“状态入栈出栈”的情况,我们把上面例子改造一下:
<canvas id="myCanvas" width="150" height="150" style="border:solid 1px #CCC;">
您的浏览器不支持canvas,建议使用最新版的Chrome
</canvas> <script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "yellow"; //注意这里多了一行状态定义
ctx.save(); //注意这里多了一行状态保存
ctx.fillStyle = "green";
ctx.fillRect(20,20,100,100);
ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(40,40,60,60);
ctx.restore(); //推出最后一个入栈的状态(fillStyle = "green")
ctx.restore(); //再次推出最后一个入栈的状态(fillStyle = "yellow"),注意green已经在上次restore推出了,故这次取到的是yellow
ctx.fillRect(60,60,20,20); //填充黄色的矩形
</script>
就像注释说明的那样,最终绘制的小矩形是黄色而非绿色:
最后介绍的是 toDataURL() 方法,它能把当前画布的内容转换为data类型的URL格式。 等等,“data类型的URL格式”又是什么来的? 有时候我们会在某些页面(比如github404页面)看到这样的图片:
其src对应的是一串“data:image/png;base64....”的data类型URL格式,返回的base64图片数据流,可以减少对服务器的图片请求(当然缺点是无法缓存在客户端)。这种格式这就是我们上面提到的东西。 那么 toDataURL() 方法的好处就显而易见了——我们可以把当前画布内容转换为一张图片。
toDataURL() 方法直接作用于canvas对象,而非context2D对象,其格式为:
url = canvas.toDataURL( [ type, ... ] )
参数type表示返回文件的MINE类型,若未指定type,则默认返回的格式必须为PNG格式。如果canvas没有任何像素,则返回值为:“data:,”,这是最短的data:URL,在text/plain资源中表现为空字符串。
type的值可以在image/png,image/jpeg,image/svg+xml 等MIME类型中选择。如果是image/jpeg,可以有第二个参数,如果第二个参数的值在0-1之间,则表示JPEG的质量等级,否则使用浏览器内置默认质量等级。
我们来个小例子:
<canvas id="myCanvas" width="150" height="150" style="border:solid 1px #CCC;"></canvas> <button onClick="openImg()">点我查看图片</button> <script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(20,20,100,100);
ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(40,40,60,60);
ctx.restore();
ctx.fillRect(60,60,20,20); function openImg(){
var image = c.toDataURL("image/png"), //注意toDataURL是canvas对象方法,而不是context2D的属性
w = window.open('about:blank');
w.document.write("<img src='"+image+"' />");
}
</script>
点击“点我查看图片”的按钮后会弹出一个新页面,上面有我们生成的base64编码形式的图片(跟canvas上绘制的内容一致):
但由于该图片是不存在于任何文件目录上的,自然也无法直接下载该(带后缀名的)文件,如果想要地道地生成一张图片供用户下载,则需要后端配合了(可以参考这里)。
另外有一点要注意的,也就是我们在第五章提到的,如果在canvas中绘制了非本地的图片,从安全性考虑将无法对其进行读操作,这种情况下如果执行toDataURL自然也会报错。不过如果资源开启了CORS,则有办法避开同源策略的阻拦(可以参考这里)。
自此,canvas的api我们基本都遍历了一遍,希望能让来此学习的朋友有所收获,共勉~
HTML5- Canvas入门(七)的更多相关文章
- HTML5 canvas入门
HTML5 Canvas入门 <canvas> 标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形.在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字. ...
- html5 Canvas绘制图形入门详解
html5,这个应该就不需要多作介绍了,只要是开发人员应该都不会陌生.html5是「新兴」的网页技术标准,目前,除IE8及其以下版本的IE浏览器之外,几乎所有主流浏览器(FireFox.Chrome. ...
- HTML5 canvas绘制线条曲线
HTML5 canvas入门 线条例子 1.简单线条 2.三角形 3.填充三角形背景颜色 4.线条颜色以及线条大小 5.二次贝塞尔曲线 6.三次贝塞尔曲线 <!doctype html> ...
- Canvas入门笔记-实现极简画笔
今天学习了Html5 Canvas入门,已经有大神写得很详细了http://www.cnblogs.com/tim-li/archive/2012/08/06/2580252.html#8 在学习过后 ...
- HTML5 Canvas 画图入门
HTML5 Canvas 画图入门 HTML5 Canvas 画图入门,仅供学习參考 <!DOCTYPE html> <html> <head> <meta ...
- 赠书:HTML5 Canvas 2d 编程必读的两本经典
赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...
- 03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素
Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 2.功能元素 1.hgroup 对网页或区段(secti ...
- 06. Web大前端时代之:HTML5+CSS3入门系列~HTML5 画布
Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 我们先看看画布的魅力: 初始画布 canvas默认是宽3 ...
- 使用html5 canvas绘制图片
注意:本文属于<html5 Canvas绘制图形入门详解>系列文章中的一部分.如果你是html5初学者,仅仅阅读本文,可能无法较深入的理解canvas,甚至无法顺畅地通读本文.请点击上述链 ...
- 使用html5 canvas绘制圆形或弧线
注意:本文属于<html5 Canvas绘制图形入门详解>系列文章中的一部分.如果你是html5初学者,仅仅阅读本文,可能无法较深入的理解canvas,甚至无法顺畅地通读本文.请点击上述链 ...
随机推荐
- 简单爬虫,突破IP访问限制和复杂验证码,小总结
简单爬虫,突破复杂验证码和IP访问限制 文章地址:http://www.cnblogs.com/likeli/p/4730709.html 好吧,看题目就知道我是要写一个爬虫,这个爬虫的目标网站有 ...
- Ubuntu菜鸟入门(八)—— QQ安装
一.下载 http://www.ubuntukylin.com/application/show.php?lang=cn&id=279 二.安装流程 1.解压,到解压文件夹中运行 sudo d ...
- Java 之 常用类(二)
1.StringBuffer a.StringBuffer 与 String:①StringBuffer是一个全新的类型,与String没有继承关系 ②StringBuffer的出现是为了解决Stri ...
- Future和Promise
Future用于获取异步操作的结果,而Promise则比较抽象,无法直接猜测出其功能. Future Future最早来源于JDK的java.util.concurrent.Future,它用于代表异 ...
- 网络神器Greasemonkey(油猴子)使用方法简介+脚本分享【转载】
推荐下,觉得这个方法有用, 今天艾薇百科来介绍一下功能强大的Greasemonkey,俗称"油猴子",Greasemonkey可以自由定制网页,实现你想要的各种功能.堪称" ...
- orm映射 封装baseDao
是用orm映射封装自己封装dao层 思路:通过映射获得实体类的属性拼接sql语句 import java.lang.reflect.Field; import java.lang.reflect.In ...
- NOI 题库 9272 题解
9272 偶数个数字3 描述 在所有的N位数中,有多少个数中有偶数个数字3? 输入 一行给出数字N,N<=1000 输出 如题 样例输入 2 样例输出 73 Solution : 令f ( ...
- 移动端Web页面问题(转载)
1.安卓浏览器看背景图片,有些设备会模糊. 用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢? 经过研究,是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率 ...
- linux 字符设备驱动写法
字符设备,块设备书 一.register_chrdev_region, register_chrdev, misc_register misc device(杂项设备) 在 Linux 内核的incl ...
- qgis自定义坐标系与qgis.db问题
将编译好的qgis库整理,屏蔽获取删除环境变量中的路径,测试qgis.exe程序功能 如出现如上提示: 原因:是未找到qgis.db文件,无法拷贝到系统默认的C:/Users/Administrato ...