html5-canvas常用的api介绍

转载请注明出处:
http://blog.csdn.net/lishihong108/article/details/52448276

在本文中主要是介绍下canvas中一些常用的、重要的函数的使用。

  • 阴影

shadowColor:设置或返回用于阴影的颜色
shadowBlur:设置或返回用于阴影的模糊级别
shadowOffsetX:设置或返回阴影距形状的水平距离
shadowOffsetY:设置或返回阴影距形状的垂直距离


其实这4个方法类似于css3的box-shadow,接下来先对比着说明下:

box-shadow: h-shadow v-shadow blur spread color inset;

css3的box-shadow的h-shadow属性等同于shadowOffsetX函数,设置阴影在水平方向便宜的距离,可以为正负,正值表示在阴影右边偏移,负值表示阴影在左边偏移;

box-shadow的v-shadow和shadowOffsetY差不多,正值表示阴影在下方偏移,负值表示阴影在上方偏移;

box-shadow的blur和shadowBlur差不多,设置阴影的模糊层次,不能为负值,设置为0表示没有模糊的层次或级别,有点区别的是,css3的box-shadow的blur是带单位px的,canvas的shadowBlur不带单位可以是浮点数;

canvas的shadowColor和css3的color属性一样,设置阴影的颜色;

可以看到css3的阴影还多了两个属性可以设置,一个是spread-阴影的扩展半径其值可以是正负值,如果值为正,则整个阴影都延展扩大,反之值为负值时,则缩小;另一个是inset-阴影的投影方式,有两个值,inset,outset(默认值)。

下面来看一个canvas绘制阴影的列子,
这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d"); 
ctx.shadowOffsetX = 2;//水平上向右偏移2px
ctx.shadowOffsetY = 2;//垂直方向上向下偏移2px
ctx.shadowBlur = 4;//模糊层次级别为4
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
ctx.font = "24px Times New Roman"; 
ctx.fillStyle = "#0A9DC7";
ctx.fillText("shadow", 5, 30);
  • 渐变

createLinearGradient(x0,y0,x1,y1):创建线性的渐变,线性变化的
参数是渐变开始点的横纵坐标、结束点的横纵坐标
这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d"); 
var gradient=ctx.createLinearGradient(0,0,140,15);
gradient.addColorStop(0,"#ff00ff");
gradient.addColorStop(0.3,"#eaeaea");//添加渐变段0-1.0之间
gradient.addColorStop(0.6,"#662233");
gradient.addColorStop(1,"#339944");
ctx.fillStyle=gradient;
ctx.fillRect(20,20,150,100);

createLinearGradient(x0,y0,r0,x1,y1,r1):创建放射状/圆形渐变,径向变化的,可以想象成一个以一个半径开始圆形的向周围扩展,就想在平静的水中,丢下一个石头,波纹扩散一样
参数是渐变点开始点横纵坐标,开始渐变的半径,渐变结束的横纵坐标,渐变结束的半径
这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d"); 
var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
radgrad.addColorStop(0, '#A7D30C');
radgrad.addColorStop(0.9, '#019F62');
radgrad.addColorStop(1, 'rgba(1,159,98,0)');
ctx.fillStyle = radgrad;
ctx.fillRect(0,0,150,150);
  • pattern

createPattern() 在指定的方向内重复指定的元素,元素可以是图片、视频,或者其他的canvas,可以用来充当画笔,填充一块画布区域
将一个图片创建为一个pattern
这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d"); 
var img = new Image();
img.src = 'img/ft.png';
img.onload = function(){ 
	var ptrn = ctx.createPattern(img,'repeat');//指定元素的重复方式,有repeat,repeat-x,repeat-y,no-repeat等方式
	ctx.fillStyle = ptrn;
	ctx.fillRect(0,0,100,80);
}

利用这个方法,我们可以方便的把其他的元素充当为画刷进行一些可控的循环绘制,类似于ps的中的画刷。

  • 线条样式

lineCap 设置或返回线条末端线帽的样式
有butt|round|square三个值可选,默认为butt
butt :向线条的每个末端添加平直的边帽
round:向线条的每个末端添加圆形线帽
square :向线条的每个末端添加正方形线帽

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d"); 
ctx.lineWidth=10;  
ctx.strokeStyle="#009689"; 
  
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(200,20);  
ctx.lineCap="butt"; 
ctx.stroke();

ctx.beginPath();
ctx.moveTo(20,40);
ctx.lineTo(200,40);
ctx.lineCap="round"; 
ctx.stroke();

ctx.beginPath();
ctx.lineCap="square"; 
ctx.moveTo(20,60);
ctx.lineTo(200,60); 
ctx.stroke();
 
ctx.lineWidth=1;
ctx.strokeText("butt",210,22); 
ctx.strokeText("round",210,42); 
ctx.strokeText("square",210,62); 

lineJoin 在两条线交汇时,设置或返回所创建边角的类型
有"bevel|round|miter 3个值,默认为miter

这里写图片描述

依次为round,bevel,miter 三种类型的表现形式

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d"); 
ctx.lineWidth=10;  
ctx.strokeStyle="#2EA879"; 
ctx.beginPath();
ctx.lineJoin="round";
ctx.moveTo(10,10);
ctx.lineTo(40,20);
ctx.lineTo(10,40);
ctx.stroke();

ctx.beginPath();
ctx.lineJoin="bevel";
ctx.moveTo(60,10);
ctx.lineTo(90,20);
ctx.lineTo(10,90);
ctx.stroke();

ctx.beginPath();
ctx.lineJoin="miter";
ctx.moveTo(110,10);
ctx.lineTo(140,20);
ctx.lineTo(10,140);
ctx.stroke();
  • 路径相关

1.ctx.beginPath():开始一条路径,或重置当前的路径 ,怎么理解这句话呢?举个例子,比如你想先画一条红色的粗细为1的线条,然后紧接着画一条粗细为10蓝色的线条。安装我们的想法代码是这样的:

 var c=document.getElementById("canvas"); 
  var ctx=c.getContext("2d");  
  ctx.moveTo(0,0); 
  ctx.lineWidth=1;  
  ctx.strokeStyle="red";
  ctx.lineTo(100,100);
  ctx.stroke();//绘制粗细为1的红色线条
  
  /*ctx.beginPath();*/
  ctx.lineWidth=10;  
  /*ctx.moveTo(100,100); */ /*开始一条新路径后要重新确定起点*/
  ctx.strokeStyle="blue";
  ctx.lineTo(100,20); 
  ctx.stroke();//绘制粗细为10的蓝色线条

这样实现了吗,有什么问题?请看该代码的效果图(图中棕色的边框是给给canvas加的border,便于查看的):

这里写图片描述

发现线条是画了两条,但是线条的状态都被第二个的线条的状态给覆盖了。
ctx.beginPath()是开始一条新路径,或重置当前路径,打开注释:

这里写图片描述

现在这个效果才是和刚才我们描述的一样的,是我们想要的效果。

2.context.closePath():创建从当前点到开始点的路径,主要是用于话封闭图形,画一个三角形:

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");  
ctx.beginPath();
ctx.moveTo(75,50);
ctx.lineTo(100,75);
ctx.lineTo(100,25);
ctx.lineTo(75,50);
//ctx.closePath();
ctx.stroke();

这里写图片描述

三角形,一个封闭的图形,我们需要最后再lineTo(75,50)这个起点,打开ctx.closePath()的注释,注释掉ctx.lineTo(75,50)可以达到同样的效果,画出一个封闭的三角形。该方法就是创建当前点到起点的路径。

  • 画布裁剪

clip() :从原始画布中剪切任意形状和尺寸。注:一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。我们可以在裁剪之前通过context.save()保存画布状态,之后在需要的时候用context.restore()恢复。

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");  
// 剪切矩形区域
ctx.fillStyle="#E6B500";
ctx.rect(50,20,200,120);
ctx.fill();
ctx.clip();
// 在 clip() 之后绘制绿色矩形
ctx.fillStyle="green";
ctx.fillRect(0,0,150,100);

绿色部分为裁剪区域。

  • 贝塞尔曲线

1.context.quadraticCurveTo(cpx,cpy,x,y),二次贝塞尔曲线

cpx:贝塞尔控制点的 x 坐标
cpy:贝塞尔控制点的 y 坐标
x:结束点的 x 坐标
y:结束点的 y 坐标

使用贝塞尔曲线绘制一个聊天的气泡

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");  
// 二次贝尔赛曲线
ctx.beginPath();
ctx.strokeStyle="#E992B9";
ctx.moveTo(75,25);
ctx.quadraticCurveTo(25,25,25,62.5);
ctx.quadraticCurveTo(25,100,50,100);
ctx.quadraticCurveTo(50,120,30,125);
ctx.quadraticCurveTo(60,120,65,100);
ctx.quadraticCurveTo(125,100,125,62.5);
ctx.quadraticCurveTo(125,25,75,25);
ctx.stroke();

2.context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y),三次贝塞尔曲线

cp1x:第一个贝塞尔控制点的 x 坐标
cp1y:第一个贝塞尔控制点的 y 坐标
cp2x:第二个贝塞尔控制点的 x 坐标
cp2y:第二个贝塞尔控制点的 y 坐标
x:结束点的 x 坐标
y:结束点的 y 坐标

画一个心型。

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");  
//三次曲线
ctx.beginPath();
ctx.fillStyle="#E992B9";
ctx.moveTo(75,40);
ctx.bezierCurveTo(75,37,70,25,50,25);
ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
ctx.bezierCurveTo(20,80,40,102,75,120);
ctx.bezierCurveTo(110,102,130,80,130,62.5);
ctx.bezierCurveTo(130,62.5,130,25,100,25);
ctx.bezierCurveTo(85,25,75,37,75,40);
ctx.fill();
  • 转换

1.scale(scalewidth,scaleheight):缩放当前绘图

scalewidth:缩放当前绘图的宽度
scaleheight :缩放当前绘图的高度

注:如果您对绘图进行缩放,所有之后的绘图也会被缩放。定位也会被缩放。如果您 scale(2,2),那么绘图将定位于距离画布左上角两倍远的位置。

这里写图片描述

右边的椭圆是左边的圆scale(2,1)得到的

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");
ctx.strokeStyle="rgb(100,20,80)";
ctx.arc(100,75,25,0,2*Math.PI);
ctx.stroke();

ctx.beginPath();
ctx.scale(2,1);
ctx.strokeStyle="red";
ctx.arc(100,75,25,0,2*Math.PI);
ctx.stroke();

2.context.rotate(angle) 旋转当前的绘图angle个角度,单位是弧度

注:旋转30度(30*Math.Pi/180)

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");
ctx.moveTo(20,20);
ctx.lineWidth=10;
ctx.strokeStyle="#007AFF";
ctx.lineTo(40,100);
ctx.stroke();


ctx.beginPath();
ctx.moveTo(20,20);
ctx.rotate(-Math.PI*60/180);
ctx.strokeStyle="#FFC900";
ctx.lineTo(40,100);
ctx.stroke();

3.context.translate(x,y):重新映射画布上的 (0,0) 位置,可以理解为平移坐标系的原点吧。

注:可以在平移前进行save(),平移之后进行restore恢复原样正常的坐标系。

接下来先画一个矩形,然后在平移坐标系原点后在画同样的矩形,可以对比起位置

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");
ctx.strokeStyle="#0A9DC7";
ctx.strokeRect(20,20,60,40);
ctx.beginPath(); 
ctx.strokeStyle="#28A54C";
ctx.translate(50,50);
ctx.strokeRect(20,20,60,40);

4.context.transform(a,b,c,d,e,f),这个其实是相当于scale,rotate,translate的组合

a 水平缩放绘图
b 水平倾斜绘图
c 垂直倾斜绘图
d 垂直缩放绘图
e 水平移动绘图
f 垂直移动绘图

5.context.setTransform(a,b,c,d,e,f),这个其实和transform功能一样,但是唯一的区别是,transform会在多次变换的基础上连续变换;但是setTransform每次都会重置,从最开始的开始变换,比如绘制一个图形a,将a用transform放大2倍,再用transform放大两倍,再绘制a,将是原来的4倍;但是setTransform同样操作的话,还是只会放大2倍,因为每次都会重置变换的矩形。

  • 像素操作

1.createImageData() :创建新的空白 ImageData 对象,新对象的默认像素值 transparent #000000

注:对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
R - 红色 (0-255)
G - 绿色 (0-255)
B - 蓝色 (0-255)
A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

这里写图片描述

创建了一个100*100的图像,每个像素点的信息的RGBA的4个值随随机的

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");
var imgData=ctx.createImageData(100,100);
for (var i=0;i<imgData.data.length;i+=4){
	imgData.data[i+0]=256*Math.random();
	imgData.data[i+1]=256*Math.random();
	imgData.data[i+2]=256*Math.random();
	imgData.data[i+3]=120;
}
ctx.putImageData(imgData,10,10);

2.getImageData(x,y,width,height) :返回 ImageData 对象,该对象会返回画布指定矩形的像素数据

x:开始复制的左上角位置的 x 坐标
y:开始复制的左上角位置的 y 坐标
width:将要复制的矩形区域的宽度
height:将要复制的矩形区域的高度

3.context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight):将图像数据(从指定的 ImageData 对象)放回画布指定的区域上

mgData:规定要放回画布的 ImageData 对象。
x ImageData:对象左上角的 x 坐标,以像素计。
y ImageData:对象左上角的 y 坐标,以像素计。
dirtyX:水平值(x),以像素计,在画布上放置图像的位置。
dirtyY :水平值(y),以像素计,在画布上放置图像的位置。
dirtyWidth :在画布上绘制图像所使用的宽度。
dirtyHeight:在画布上绘制图像所使用的高度。

下面一个例子,将通过这两个方法更改图像的色彩:

原来的图片
这里写图片描述

改变后:
这里写图片描述

我们可以利用这两个方法对图片进行修整

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");
var img = new Image();
img.src = 'img/flower.jpg';
img.function(){ 
	ctx.drawImage(img,0,0);
	var imgData=ctx.getImageData(0,0,c.width,c.height);
	// 反转颜色
	for (var i=0;i<imgData.data.length;i+=4){
		imgData.data[i]=255-imgData.data[i];
		imgData.data[i+1]=255-imgData.data[i+1];
		imgData.data[i+2]=255-imgData.data[i+2];
		imgData.data[i+3]=255;
	}
	ctx.putImageData(imgData,0,0);
};
  • globalCompositeOperation :将一个源(新的)图像绘制到目标(已有)的图像上
    源图像:打算放置到画布上的绘图
    目标图像 : 已经放置在画布上的绘图

有以下属性可以设置:

source-over:默认,在目标图像上显示源图像
source-atop:在目标图像顶部显示源图像,源图像位于目标图像之外的部分是不可见的
source-in:在目标图像中显示源图像,只有目标图像内的源图像部分会显示,目标图像是透明的
source-out:在目标图像之外显示源图像,只会显示目标图像之外源图像部分,目标图像是透明的
destination-over:在源图像上方显示目标图像
destination-atop:在源图像顶部显示目标图像,源图像之外的目标图像部分不会被显示
destination-in:在源图像中显示目标图像,只有源图像内的目标图像部分会被显示,源图像是透明的
destination-out:在源图像外显示目标图像,只有源图像外的目标图像部分会被显示,源图像是透明的
lighter:显示源图像 + 目标图像
copy:显示源图像,忽略目标图像
source-over:使用异或操作对源图像与目标图像进行组合

这里写图片描述

var c=document.getElementById("canvas"); 
var ctx=c.getContext("2d");

ctx.fillStyle="#11C1F3";
ctx.fillRect(10,10,30,20);
ctx.globalCompositeOperation="source-over";
ctx.fillStyle="#E992B9";
ctx.fillRect(20,20,30,20);

ctx.beginPath();
ctx.fillStyle="#11C1F3";
ctx.fillRect(70,10,30,20);
ctx.globalCompositeOperation="source-atop";
ctx.fillStyle="#E992B9";
ctx.fillRect(80,20,30,20);

其他属性大家可以自行测试看看之间的区别。

  • canvas的context当前状态的保存context.save(),恢复context.restore(),这个在绘图的过程中很重要,经常用到

后面再绘制复杂的canvas中会详细介绍这两个方法的用处。

关于canvas方法属性参考W3c-school

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值