创建canvas画布
1 | css: |
Point:
canvas标签是一个双标签,其内部写的是当浏览器不支持canvas时显示的内容,可以插入其他元素,比如文字,图片等。
canvas画布的宽高应该在其标签内定义,不能在其CSS内定义,否则其绘制的图像会按照300*150发生缩放。
所有绘图行为都在script标签中进行。
let ctx = canvas.getContext(“2d”);
所有canvas的API都是定义在该对象上的,其中参数可以是2D,或者3D.
Canvas绘制图像
canvas的绘制图形有两种方式:
- context.fill()
fill()指的是填充,其默认颜色是黑色,可以在使用fill()之前使用fillStyle()方法改变填充颜色,如果是闭合图像,那么就直接填充。如果是非闭合的路径,则fill()先帮其闭合,然后填充。
1 | ctx.fillStyle = "red";//设置填充色 |
- context.stroke()
stroke()方法会实际的绘制出moveTo()和lineTo()方法的路径。默认颜色是黑色,在绘制之前,可以使用strokeStyle()进行设置。
1 | ctx.strokeStyle = "red";//设置边框填充色 |
绘制矩形
绘制基本矩形
1 | ctx.fillRect(x,y,height,width)//实心矩形 |
- x:起点的x坐标(即左上角的x坐标)
- y:起点的y坐标(即左上角的y坐标)
- height:矩形的高
- width:矩形的宽
改变颜色
1 | ctx.fillStyle = "red";//设置填充颜色 |
Point:
- ctx.fillStyle = “red”用来设置填充颜色
- ctx.strokeStyle = “red”用来设置边框颜色
- 这些描述都要放在绘制图形之前声明
擦除矩形区域
ctx.clearRect(x,y,height,width)
ctx.clearRect(50,50,200,200)//绘制一个矩形区域并擦除该区域之前的内容
绘制圆形
绘制基本圆
实心圆
ctx.arc(x,y,radius,starAngle,endAngle,anticlockwise)
- x:圆心的x坐标
- y:圆心的y坐标
- radius:半径
- startAngle:开始角度
- endAngle:结束角度
- anticlockwise:旋转方向,
- true:逆时针(可选参数,默认为false)
- false:顺时针
1
2
3ctx.fillStyle = "red"; //设置填充色
ctx.arc(200,200,50,0,Math.PI*2,true);//绘制圆形
ctx.fill();//填充
空心圆
1 | ctx.beginPath() |
Point
上面用到了路径,实际ctx.arc()相当于是一个lineTo()的一个集合。利用其绘制出一个圆形,最后要关闭(ctx.cloePath()),以及要(stroke())才能完全绘制出该图形。
非完整圆
如果要绘制一个非完整的圆,比如一个实心半圆,该如何绘制呢?
答案是使用arc方法中的startAngle和endAngle来改变。
1 | ctx.fillStyle = "red"; |
空心圆形
1 | ctx.beginPath(); |
绘制线段
moveTo(x,y):把画笔移动至画布的制定位置,不创建线条
lineTo(x,y):添加一个点(x,y)
stroke():按照之前添加的点绘制路径
1
2
3
4ctx.strokeStyle = "red";//设置填充色
ctx.moveTo(0,0);//将画笔移动至(0,0)
ctx.lineTo(100,100);//添加一个点(100,100)
ctx.stroke();//按点绘制路径
Point
如果没有在第一次指定moveTo(x,y),则第一个lineTo(x,y) == moveTo(x,y)
如果在lineTo()后没有使用moveTo()方法,则依次连接,eg:
ctx.moveTo(0,0);
ctx.lineTo(10,10);
ctx.lineTo(20,20);
ctx.lineTo(30,30);
ctx.stroke();
则画出后是一段从点(0,0)=>(10,10)=>(20,20)=>(30,30)的一段折线。
- ctx.beginPath():开始一段路径
- ctx.closePath():闭合路径,即canvas会自动将未闭合的线段的首尾连接起来。
eg(一个三角形):
1 | ctx.beginPath(); |
案例(六边形):
1 | var n = 0; |
Point
这个例子用了一点数学知识,主要是:
1 | for (var i = 0; i < 6; i++) { |
其原理是利用了简单的沟股定理,计算下一个点的坐标
线性渐变
- let lg = ctx.createLinearGradient(xStart,yStart,xEnd,yEnd)
- lg.addColorStop(offset,color)
- xSart:渐变开始点的x坐标
- yStart:渐变开始点的y坐标
- xEnd:渐变结束点的x坐标
- yEnd:渐变结束点的y坐标
- offset:设定的颜色离渐变结束点的偏移量
- color:绘制的颜色
eg:
let lg = ctx.createLinearGradient(0,0,100,200);
lg.addColorStop(0,”#E55D87”);
lg.addColorStop(1,”#5FC3E4”);
ctx.fillStyle = lg;
ctx.fillRect(0,0,200,200);
Point
- 线性渐变仅仅是相当于设置填充色,在定义完填充色之后,我们还需要将填充设置为该线性渐变
(ctx.fillStyle = gl)
- 由于线性渐变仅仅是设置填充色,所以具体的背景容器还需要我们自己设置,比如设置一个矩形作为容器
ctx.fillRect(0,0,200,200)
- 由于渐变背景的坐标是相对于画布,而图形的坐标也是相对于画布,所以在定义背景时,需要注意与图形的坐标搭配以达到需要的效果
径向渐变
1 | let rg = ctx.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd) |
xSart:发散开始的圆心x坐标
yStart:发散开始的圆心y坐标
radiusStart:发散开始圆的半径
xEnd:发散结束圆心的x坐标
yEnd:发散结束圆心的y坐标
radiusEnd:发散结束圆的半径
offset:设定的颜色结束点的偏移量(0-1)
color:绘制颜色
1
2
3
4
5
6
7
8var g1 = ctx.createRadialGradient(200, 150, 0, 200, 150, 200);
g1.addColorStop(0.1, '#F09819');
g1.addColorStop(1, '#EDDE5D');
ctx.fillStyle = g1;
ctx.beginPath();
ctx.arc(200, 150, 100, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
图形变形
缩放
scale(x,y)
x:x坐标轴按x比例缩放
y:y坐标轴按y比例缩放
前面参数的是按倍数来衡量的(0.5=>50%,1=>100%,2=>200%)
eg:
1 | ctx.strokeStyle = "red"; |
Point
- 缩放一个图形,先使用
ctx.scale(x,y)
对画布进行缩放处理,后面再创建要缩放的工具ctx.strokeRect(5,5,25,15);
。 - 缩放的原点都是在(0,0)位置。
旋转
ratate(angle)
angle:旋转的角度,以弧度计。
eg:
1 | ctx.strokeStyle = "red"; |
Point:
默认的旋转中心是在(0,0)位置。下面介绍如何改变旋转中心。
平移
translate(x,y)
x:坐标原点向x轴平移x
y:坐标原点想y轴平移y
eg1(以矩形中心为原点旋转):
1 | ctx.strokeStyle = "red"; |
eg2(以矩形中心为原点缩放图形):
1 | ctx.strokeStyle = "red"; |
Point
上面提到的,scale,rotate方法的操作都是对画布而言的,貌似整的canvas的思维都是这样,需要我们有反向思考的能力。
组合图形
1 | globalCompositeOperation = type |
后绘制的图形如何与之前的图像叠加渲染,取决于type。下面是type的种类:
- source-over(默认):在原图形之上绘制(覆盖)。
- destination-over:在原图形之下绘制。
- source-in:显示原有图形和新图形的交集,新图形在上,所以颜色为新图形颜色
- destination-in:显示原图形和新图形的交集,原图形在上,所以颜色为原图形的颜色
- source-out:只显示新图形的非交集部分
- destination-out:只显示旧图形的非交集部分
- source-atop:显示原图形和交集部分,新图形在上,所以交集部分为新图形颜色
- destination-atop:显示新图形和交集部分,新图形在上,所以交集部分为新图形颜色
- lighter:显示原有图形和新图形,交集部分做颜色叠加
- copy:只显示新图形
eg:
1 | ctx.globalCompositeOperation = "lighter"; |
Point
该属性与上面的ctx.translate(x,y)
一样,一旦作用,就对下面的元素都起作用,如果要还原,请在此使用该属性还原。
阴影
- shadowOffsetX:设置或返回阴影距形状的水平距离(默认值为0)
-shadowOffsetY:设置或返回阴影形状的垂直距离(默认值为0) - shadowColor:设置或返回阴影的颜色
- shadowBlur:设置或返回阴影的模糊级别(值越大越模糊)
eg:
ctx.shadowOffsetX=20;
ctx.shadowColor=”blue”;
ctx.shadowBlur = 50;
ctx.fillStyle = “red”;
ctx.fillRect(100,100,200,200);
1 | ctx.shadowBlur = 0; |
Point
相同的是,阴影属性也是对一下的所有图形都生效。要取消阴影效果,必须重置:
1 | ctx.shadowBlur = 0; |
图像操作
- drawImage(img,x,y):在画布上定位图像
- drawImage(img,x,y,width,height):在画布上定位图像,并规定图像的宽度和高度
- drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
- img:规定要使用的图像,画布或视频
- sx(可选):开始剪切的x坐标位置
- sy(可选):开始剪切的y坐标位置
- swidth(可选):被剪切的图像的宽度
- sheight(可选):被剪切的图像的高度
- x:在画布上放置img的x坐标位置
- y:在画布上放置img的y坐标位置
- width(可选):要使用的图像的宽度。(拉伸或压缩)
- height(可选):要使用的图像的高度。(拉伸或压缩)
eg:
1 | let img = new Image(); |
Point
img应该是一个img对象,
img = new Image()
或者是一个Image的DOM标签document.getElementById("img")
(实际也是一个Image对象,因为在HTML中,每创建一个img标签,就会自动创建一个Image对象。)在使用该标签时,应当使用,Image对象的回调函数onload,否则不能渲染成功,其原因是:
1
2let img = new Image();
img.src = "expi.jpg";这个过程中,对img.src赋值的时候,可能还没有赋值完成,就进行了
ctx.drawImage
语句,由于还没赋值完成,此使img.src还是空,所以无法渲染出来。
图像平铺
- createPattern(image,type)
type:
- no-repeat:不平铺
- repeawt-x:按x轴方向平铺
- repeat-y:按y轴方向平铺
- repeat:全方向平铺
eg:
let img = new Image;
img.src = “beauty.png”;
img.onload = function(){
let pattern = ctx.createPattern(img,”repeat-x”);
ctx.fillStyle = pattern;
ctx.fillRect(10,10,500,500);
}
Point
- 相同的是,必须要配合Image的oload回调函数来使用,道理同上。
图像剪切
- clip()
该函数的使用方法:
- 创建剪切区域:ctx.rect(x,y,width,heigth)
- 设置剪切部分的填充色:ctx.fillStyle = “pink”
- 进行填充:ctx.fill();
- 进行剪切:ctx.clip();
eg:
1 | ctx.fillStyle = "yellow"; |
Point
-一旦剪切了某个区域,则之后的所有绘图都会被限制在被剪切区域内进行(不能访问画布上的其他区域)。我们也可以在使用clip()方法之前通过使用save()方法将之前的画布保存下来,并在任意时间使用restored()方法。
绘制文字
- fillText(text,x,y):绘制实心文字
- x:文字的中心点x坐标
- y:文字的中心点y坐标
- strokeText():绘制文字描边(空心文字)
- textAlign:设置或返回文字内容的当前对齐方式(注意:其都是相对于该文字对象的中心),其值有:
- start:默认。文本在指定的位置开始。
- end:文本在指定的位置结束。
- left:文本左对齐。
- center:文本的中心被放置在指定的位置。
- right:文本右对齐。
- textBaseline:设置会返回在绘制文本时使用的当前文字基线,其值有:
- Bottom:文本基线是 em 方框的底端。
- Top:文本基线是 em 方框的顶端。
- Middle:文本基线是 em 方框的正中。
- Alphabetic:默认。文本基线是普通的字母基线。
- hanging:文本基线是悬挂基线。
- font:设置或返回文本内容的当前文字属性
eg:
1 | ctx.font = "40px Arial"; |