这篇是canvas API系列的首尾之做,这篇之后,全部的canvas的属性和方法就将完了,哦,不对,应该是大部分经常使用的,还有部分不经常使用的属性和方法,由于种种缘由,就不介绍了,后期的重点就是多写一点canvas的实践小实例了,恩,我以为这才是最实用的,俗话说一例抵千言啊,废话很少说,咱们来看看剩下的一些属性和方法吧!css
一、createPatterncanvas
createPattern(image,"repeat|repeat-x|repeat-y|no-repeat") 在指定的方向上重复指定的元素数组
参数: image指实用的图片,画布或者是视频对象 第二个参数表示重复的方式app
看这后面的参数,很容易想到css中的background-repeat,第一个参数我得说一下,这里跟background不同,不是引用的图片地址,而是一个图片对象,这里特别注意,咱们分别看一下这些重复方式的表现:this
var aImg = new Image(); aImg.src = '4.jpg'; aImg.onload = function(){ draw(this); } function draw(obj){ //这里为了演示方便,把其余的先注释 //var bg = ctx.createPattern(obj,"repeat"); //var bg = ctx.createPattern(obj,"repeat-x"); //var bg = ctx.createPattern(obj,"repeat-y"); var bg = ctx.createPattern(obj,"no-repeat"); ctx.fillStyle = bg; ctx.fillRect(0,0,400,400); }
恩,跟css的background-repeat的效果是同样的,那就好理解了,可是canvas是没有background-position的,恩,这个效果就是这样,没什么好讲的!spa
具体效果看这里 —— canvas 背景重复翻译
二、gloableCompositeOperation3d
gloableCompositeOperation() 设置或返回新图像如何绘制到已有的图像上code
参数:视频
source-over 默认,在目标图像上显示源图像。
source-atop 在目标图像顶部显示源图像。源图像位于目标图像以外的部分是不可见的。
source-in 在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。
source-out 在目标图像以外显示源图像。只会显示目标图像以外源图像部分,目标图像是透明的。
destination-over 在源图像上方显示目标图像。
destination-atop 在源图像顶部显示目标图像。源图像以外的目标图像部分不会被显示。
destination-in 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
destination-out 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
lighter 显示源图像 + 目标图像,即相交部分图形前后填充来增长亮度
copy 显示源图像。忽略目标图像,即只显示源图像
xor 使用异或操做对源图像与目标图像进行组合,即相交部分为透明
不经常使用的:
multiply 源图像的像素乘以目标图像的像素
screen
overlay
darken 加深,相交部分图形前后填充来下降亮度
lighten 加亮,相交部分图形前后填充来增长亮度
color-dodge 将底层调到顶层,即将目标图像调到源图像上方
color-burn 将底层调到顶层,而后反转
hard-light 将底层调到顶层,而后 multiply效果与screen叠加
soft-light
difference
exclusion
hue
saturation
color
luminosity
因为英文很差,部分的经常使用的参数的意思不太好解释,为了避免误导你们,我就不翻译了,若是有英文比较好的,看看这里 gloableCompositeOperation参数解释 ,要是能比较清楚的翻译的话,但愿你能把翻译的意思告诉我,不胜感谢,英语是硬伤啊!不事后面的运行结果我会给到你们参考!
参数不少,咱们先看看经常使用的,前面八个很好理解,就是一个反的,首先咱们须要理解,什么是目标图形?什么是源图形?
目标图像 = 您已经放置在画布上的绘图;源图像 = 您打算放置到画布上的绘图。这是官方的解释,若是你对这个解释不理解,咱们能够这么理解,就是先画的图像是目标图形,后画的图像是源图像,例如:
//目标图像 ctx.fillStyle="red"; ctx.fillRect(20,20,75,50); ctx.globalCompositeOperation="source-over"; //源图像 ctx.fillStyle="blue"; ctx.fillRect(50,50,75,50);
固然这个gloableCompositeOperation的位置不是固定的,能够放到目标图像前面,也能够放到目标图像后面,可是不能放到源图像后面(大家懂的),参数意思如很差理解,看下图,看看是什么表现:
var arr = ['source-over','source-atop','source-in','source-out','destination-over','destination-atop','destination-in','destination-out','lighter','copy','xor','multiply','screen','overlay','darken','lighten','color-dodge','color-burn','hard-light','soft-light','difference','exclusion','hue','saturation','color','luminosity']; for(var i=0;i<arr.length;i++){ document.write("<div id='p_" + i + "' style='float:left;'>" + arr[i] + ":<br>"); var canvas = document.createElement("canvas"); canvas.width = 120; canvas.height = 100; canvas.style.border = "1px solid #000"; canvas.style.marginRight = '10px'; document.getElementById("p_" + i).appendChild(canvas); var ctx = canvas.getContext("2d"); ctx.fillStyle="red"; ctx.fillRect(10,10,50,50); ctx.globalCompositeOperation=arr[i]; ctx.beginPath(); ctx.fillStyle="green"; ctx.fillRect(30,30,50,50); ctx.fill(); document.write("</div>"); }
红与绿
红与蓝
具体效果你也能够看这里 —— canvas图形组合模式
里面的代码我故意把canvas的代码留在上面,方便大家查看,不知道你看到这些参数有什么感想,个人第一感受就是有些熟悉比clip好用,也让我第一时间想到了这一个效果:
ctx.fillStyle="red"; ctx.arc(150,150,100,0,360*Math.PI/180,false); ctx.fill(); ctx.globalCompositeOperation="xor"; ctx.beginPath(); ctx.arc(150,150,80,0,360*Math.PI/180,false); ctx.fill();
若是配合前面的扇形方法,很容易作一个圆形进度条什么的,固然,还有不少属性能够有大的做用,好比说裁切一个图形,发挥的发达的大脑吧,这里我就不演示了
三、setLineDash
setLineDash(arr) 在画布上画一条虚线
参数:arr 表示的是一个数组集合,里面的参数能够有多个,这里面的参数颇有意思,举个栗子说明:
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20]); ctx.stroke();
对比代码看图,若是有2个参数,则第一个参数表示虚线的线宽,第二个参数表示虚线的线与线的距离,后面一直循环
若是是3个参数呢?
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20,30]); ctx.stroke();
此时会这样,第一条线长为10,而后间距为20,第2条线长为30,而后间距为10,第3条线长20,而后间距为30,处处为一个循环,后面重复
那么4个参数就好理解了,
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20,30,40]); ctx.stroke();
规律和上面的同样,只是循环的长度要长一些,更多参数的规则也是这样的,那么一个参数是否有效呢
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10]); ctx.stroke();
显然是有效的,此时线宽为10,间距为10,这就是华丽的分割线的作法
它还有一个兄弟用法,这个是设置虚线,那么就会有一个获取虚线
getLineDash() 获取当前虚线的样式
它没有参数,它获得的结果就是设置虚线的线宽数组arr,咱们看一下怎么用:
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10]); var txt = ctx.getLineDash(); ctx.stroke(); ctx.fillStyle = 'red'; ctx.font = "30px Arial"; ctx.fillText(txt,180,140);
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20]); var txt = ctx.getLineDash(); ctx.stroke(); ctx.fillStyle = 'red'; ctx.font = "30px Arial"; ctx.fillText(txt,180,140);
从这两组图能够看出,当只有一个参数数,会默认为2个同样的参数
四、isPointInPath
isPointInPath(x,y) 指定点是否在路径区域中,若是在则返回true,不在则返回false
参数: x,y表示指定的坐标点
举个栗子:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.fillStyle = 'red'; ctx.rect(50,50,100,100); ctx.fill(); canvas.onclick = function(ev){ var ev = ev || event; ctx.clearRect(200,0,200,200); var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInPath(l,t)){ ctx.font = "40px Arial"; ctx.fillText((l+','+t),200,120); } }
看看这个gif图,当点击红色区域时,我将坐标打印出来,若是点击的地方不在红色区域,则不显示坐标,具体效果看这里 —— canvas判断是否在路径区域
这里有一点须要注意,就是在绘制矩形时,不能用fillRect或strokeRect,为何呢?由于这里判断是是否在指定的路径中,而fillRect或strokeRect此时已经不是路径了,而是变成了填充过的图形,因此这里必须先用Rect()定义一下路径,再填充,这样才能回去到指定图形的路径,此点须知!
还有一个方法:
isPointInStroke(x,y) 指定点是否在路径中,若是在则返回true,不在则返回false
此方法跟上面的方法很类似,不一样点在于,isPointInPath是在一个区域中,不论是用fill仍是stroke,可是isPointInStroke只能用stroke填充,且指定的区域是在线框上,看下面的例子:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.strokeStyle = 'red'; ctx.lineWidth = 5; ctx.rect(50,50,100,100); ctx.stroke(); canvas.onclick = function(ev){ var ev = ev || event; ctx.clearRect(200,0,200,200); var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInStroke(l,t)){ ctx.font = "40px Arial"; ctx.fillText((l+','+t),200,120); } }
从这个gif中能够看出端倪来,只有点到线框才会触发,具体效果看这里 —— canvas 判断是否在线框中
这2个方法的基本用法就是这样,可是会有一个问题,就是目前只有一个图形在上面,若是有2个图形在上面,并且分别的方法不同,好比说,一个是区域路径,一个是线框路径,分别点击他们,弹出不一样的值,咱们看行不行:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.strokeStyle = 'red'; ctx.lineWidth = 5; ctx.rect(50,50,100,100); ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.fillStyle = 'green'; ctx.rect(200,50,100,100); ctx.fill(); ctx.closePath(); canvas.onclick = function(ev){ var ev = ev || event; var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInStroke(l,t)){ console.log('线框路径'); } } canvas.onclick = function(ev){ var ev = ev || event; var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInPath(l,t)){ console.log('区域路径'); } }
看看console里面的提示,当点击区域路径的时候,触发了操做,可是点击线框路径时,不管我怎么点击,都无济于事,这是为何呢?把2图形的执行顺序颠倒一下,发现效果也相反了,说明谁最后绘制就执行谁,其实这也是能够理解的,由于此时的ctx指的是当前的路径,它不能分当前路径一,路径二什么的,若是要实现多个图形执行不一样的事件,又改如何作呢?因为实现方法有点复杂,就在这里留一个思考题?大家先思考一下,该怎么弄?我会到后期单独写一篇文章,专门来讲这个的解决方案,供你们参考!
恩,处处全部该讲的canvas API就所有讲完了,看了这一系列的文章,不知道你是否对canvas有了那么一点点的感受,是否canvas已经不那么神秘了,若是你嘴上不说,内心以为,恩,好像有点感受了,那个人目的就达到了,要是你还能写一些效果,那恭喜你,距离大神你有近了一步,若是有时间,有能力,我但愿能多写一下有点深度的canvas实例给你们参考,希望能对你们有帮助!
就这样吧,感谢你们的关注,谢谢!