这篇是canvas API系列的首尾之作,这篇以后,所有的canvas的属性和方法就将完了,哦,不对,应该是大部分常用的,还有部分不常用的属性和方法,因为种种原因,就不介绍了,后期的重点就是多写一点canvas的实践小实例了,恩,我觉得这才是最实用的,俗话说一例抵千言啊,废话不多说,我们来看看剩下的一些属性和方法吧!

1、createPattern

createPattern(image,"repeat|repeat-x|repeat-y|no-repeat")  在指定的方向上重复指定的元素

参数: image指实用的图片,画布或者是视频对象 第二个参数表示重复的方式

看这后面的参数,很容易想到css中的background-repeat,第一个参数我得说一下,这里跟background不一样,不是引用的图片地址,而是一个图片对象,这里特别注意,我们分别看一下这些重复方式的表现:

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的,恩,这个效果就是这样,没什么好讲的!

具体效果看这里 —— canvas 背景重复

2、gloableCompositeOperation

gloableCompositeOperation()  设置或返回新图像如何绘制到已有的图像上

参数:

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();

如果配合前面的扇形方法,很容易做一个圆形进度条什么的,当然,还有很多属性可以有大的作用,比如说裁切一个图形,发挥的发达的大脑吧,这里我就不演示了

3、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个一样的参数

4、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实例给大家参考,但愿能对大家有帮助!

就这样吧,感谢大家的关注,谢谢!

canvas API ,通俗的canvas基础知识(六)的更多相关文章

  1. python基础知识六 文件的基本操作+菜中菜

    基础知识六 文件操作 ​ open():打开 ​ file:文件的位置(路径) ​ mode:操作文件模式 ​ encoding:文件编码方式 ​ f :文件句柄 f = open("1.t ...

  2. Python基础知识(六)------小数据池,集合,深浅拷贝

    Python基础知识(六)------小数据池,集合,深浅拷贝 一丶小数据池 什么是小数据池: ​ 小数据池就是python中一种提高效率的方式,固定数据类型使用同一个内存地址 代码块 : ​ 一个文 ...

  3. ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF)

    先上一段代码,了解一下 .NET Core 配置数据的结构. 新建一个 控制台项目,添加一个文件 json.json ,文件内容如下: { "country": "cn& ...

  4. C#基础知识六之委托(delegate、Action、Func、predicate)

    1. 什么是委托 官方解释 委托是定义方法签名的类型,当实例化委托时,您可以将其实例化与任何具有兼容签名的方法想关联,可以通过委托实例调用方法. 个人理解 委托通俗一点说就是把一件事情交给别人来帮助完 ...

  5. 【基础知识六】支持向量机SVM

    开发库: libsvm, liblinear      GitHub地址 SVM难点:核函数选择 一.基本问题 找到约束参数ω和b,支持向量到(分隔)超平面的距离最大:此时的分隔超平面称为“最优超平面 ...

  6. oracle基础知识(六)----spfile与pfile

    一, 认识参数文件      Oracle中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件.它们是在数据库实例启动时候加载的,决定了数据库的物理 结构.内存.数据库的限制及系统大量的默认值 ...

  7. Go语言核心36讲(Go语言基础知识六)--学习笔记

    06 | 程序实体的那些事儿 (下) 在上一篇文章,我们一直都在围绕着可重名变量,也就是不同代码块中的重名变量,进行了讨论.还记得吗? 最后我强调,如果可重名变量的类型不同,那么就需要引起我们的特别关 ...

  8. python基础知识六

    博客园的博文对每篇博文的长度似乎做了限制 面向对象编程, 在程序何种,根据操作数据的函数或语句块来设计程序.这被成为面向过程的编程.还有一种把数据和功能结合起来,用称为对象的东西包裹起来组织组织程序的 ...

  9. java 基础知识六 字符串2

    java  基础知识六  字符串2 1.String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法 . String 是不可变对象,也就是一旦创建,那么整 ...

  10. java 基础知识六 字符串1

    java  基础知识六  字符串1 String 不是java的基本数据类型 String 不是java的基本数据类型 String 不是java的基本数据类型 字符串是是一个字符序列 1.创建 创建 ...

随机推荐

  1. C 文件读写2

    feof() int  feof(FILE *stream); 在执行读文件操作时,如果遇到文件尾,则函数返回逻辑真(1):否则,则返回逻辑假(0). feof()函数同时适用于ASCII码文件和二进 ...

  2. 在Ubuntu下安装*.sh

    在Ubuntu下安装*.sh和*.bin的方法 [日期:2009-12-07] 来源:Linux公社  作者:Linux编辑 [字体:大 中 小]   记下在Ubuntu下安装*.sh和*.bin的简 ...

  3. KMP 算法总结

    KMP算法是基本的字符串匹配算法,但是代码实现上有一些细节容易错.这篇随笔将认真总结一下. KMP算法的核心是: The KMP algorithm searches for occurrences ...

  4. A.3 词法分析器

    包 lexer 是词法分析器的代码的扩展.类 Tag 定义了各个词法单元对应的常量. 1: package lexer; 2: public class Tag { 3: public final s ...

  5. Chrome浏览器插件

    Chrome 布局 1. 修改Chrome Dock side Chrome 更多工具 -> 开发者工具 -> Customsize and Control Dev Tools

  6. 采用httpclient提交数据到服务器

    1)Get提交数据 效果演示:

  7. jquery------.mouseover()和.mouseout()的高级效果使用

    index.jsp <div style="width:100%;height:40px;background-color:#aaa;position:absolute;"& ...

  8. hdu 2044 一只小蜜蜂

    斐波那契数列变形,在本题中不是从1-N,而是从M-N 下标   1   2   3   4   5   6   7     8     9 值     1   1   2   3   5   8   ...

  9. python购物&常用字符处理方法

    python 一个购物车的例子 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 '''购物车''' 4 5 goods = [ 6 7 {&quo ...

  10. Ueditor配置及在项目中的使用

    引言 上篇中简单介绍了Ueditor的两种定制方式,想了解的请戳这里:Ueditor的两种定制方式.在项目中,Ueditor该怎么使用更方便呢?很容易让人想到将ueditor放入用户控件页,可以拖到需 ...