面试知识点总结 - js Canvas

1. canvas介绍

  1. canvas元素:可以通过width、height设定一个区域,然后通过js动态在该区域中绘制图形;如果浏览器不支持canvas,则会显示canvas标签中的内容
  2. canvas元素有2D绘图上下文和3D绘图上下文(WebGL)
  3. canvas元素的原点在左上角,坐标为(0,0)

2. canvas元素的方法

  1. getContext(‘2d’):获取2D绘图上下文,可以通过调用该对象的方法属性画各种图形
  2. toDataURL(‘image/png’):导出在canvas元素上绘制的图形,参数为MIME类型格式,返回值为base64编码的图片URL地址
<canvas id='drawing' width='300' height='300'>on canvas</canvas>
let drawing = document.querySelector('#drawing');
if(drawing.getContext){
	let ctx = drawing.getContext('2d');
	//绘制图形....
	let imgurl = drawing.toDataURL('image/png');
	let img = new Image();
	img.src = imgurl;
	document.body.appendChild(img);	
}

3. 2D绘图上下文的方法和属性

  1. 2D绘图上下文可以绘制矩形、弧形、路径、文本、图像、阴影、变换;生成渐变对象、模式对象;获取和更改图像数据;绘制方式有填充和描边
  2. 填充和描边
  1. fillStyle:设置填充的样式的属性,一般为颜色;属性值可以为字符串、渐变对象、模式对象;颜色可以为颜色名、十六进制、rgb、rgba、hsl、hsla;默认值为#000;
    ctx.fillStyle = ‘#ddd’
  2. strokeStyle:设置描边的样式的属性;设置同fillStyle
    ctx.strokeStyle = ‘#ddd’
  3. 以上两个属性为填充和描边的样式基础
  1. 描边线条相关属性
  1. lineWidth:描边线条的宽度
  2. lineCap:描边线条的末端形状;圆头(round)、方头(square)、平头(butt)
  3. lineJoin:描边线条的相交方式;圆交(round)、斜交(bevel)、斜接(miter)
  1. 绘制矩形

这三个方法都接收4个参数,矩形的x和y坐标、矩形的宽和高、单位为像素

  1. fillRect(x,y,width,height)
  2. strokeRect()
  3. clearRect():清除画布上的矩形区域,本质上是把绘制上下文的某个矩形区域变透明,通过绘制形状然后在清除指定区域
  1. 绘制路径
  1. 弧度
  1. 圆心角的弧度数(弧度):弧长与半径的比,2πr/r = 2π = 360°,所以π = 180°
  2. 度量角的方法:度(°)和弧度(rad)
  3. 弧度/2π = 角度/360°
  1. 创建路径后,可以使用以下方法
  1. closePath():连接到路径的起点
  2. fill():路径填充,用fillStyle属性的样式
  3. stroke():路径描边,用strokeStyle属性的样式
  4. clip():在路径上创建一个剪切区域
  1. 绘制路径
  1. fillRect()方法绘制的矩形时独立的形状,绘制的路径不是独立的,回和其他路径、其他点等连接起来,当前点会连接到上一个点
  2. beginPath():必须先调用该方法,表示开始绘制新路径;在调用其他方法来绘制路径
  3. arc(x,y,radius,startAngle,endAngle,counterclockwise):以(x,y)为圆心,以radius为半径画弧线,起始和结束角度(用弧度表示)分别为startAngle和endAngle;最后一个参数表示开始和结束角度是否逆时针计算;默认为false,顺时针
  4. arcTo(x1,y1,x2,y2,radius):从上一个点开始绘制一条弧线,到(x2,y2)为止,以radius为半径,穿过(x1,y1)
  5. lineTo(x,y):从上一个点开始绘制一条直线,到(x,y)为止
  6. moveTo(x,y):将绘图游标移动到(x,y),不画线
  7. rect(x,y,width,height):从(x,y)点开始绘制一个矩形,宽度和高度分别为width和height,这个方法绘制的是矩形路径,不是独立的,回和其他点相连
  8. quadraticCurveTo(cx,cy,x,y):从上一点开始绘制一条二次曲线,到(x,y)为止,并以(cx,cy)为控制点
  9. bezierCurveTo(c1x,c1y,c2x,c2y,x,y):从上一个点开始绘制一条曲线,到(x,y)为止,并以(c1x,c1y)和(c2x,c2y)为控制点
  10. isPointInPath(x,y):在路径关闭之前,确定画布上的指定点(x,y)是否在路径上
  1. 绘制文本

两个方法都接收4个参数,要绘制的文本字符串、开始绘制的x,y坐标、可选的绘制文本的最大像素宽度

  1. 绘制文本的方法
  1. fillText(str,x,y,maxwidth):以fillStye属性的样式为基础
  2. strokeText():以strokeStyle属性的样式为基础
  3. 最后一个参数为,要绘制的文本的最大像素宽度,当该宽度小于要绘制的文本的宽度时,绘制的宽度会收缩以适应最大宽度,高度不变
  1. measureText(str):确定文本大小,参数为要绘制的文本,返回一个TextMetrics对象,里面有width等属性
  2. 涉及到的绘制属性,绘制文本以这3个属性为基础
  1. font:文本样式、大小、字体;同css中的font的格式
  2. textAlign:文本的水平对齐方式;有center、start、end、left、right
  3. textBaseline:文本的垂直对齐方式;有top、bottom、middle、hanging、alphabetic、ideographic
  1. 绘制图像
  1. drawImage()方法的9个参数
  1. img:要绘制的源图像,可以为<img>元素或者另一个<canvas>元素
  2. sx、sy:要绘制的源图像的起点坐标(x,y)
  3. swidth、sheight:要绘制的源图像的宽高
  4. x、y:在画布上,绘制后的目标图像的起点坐标
  5. width、height:在画布上,绘制后的目标图像的宽高
  1. drawImage()方法绘制图像的三种用法
  1. 把一副图像绘制到画布上
    drawImage(img,x,y)
  2. 改变绘制后的目标图像的大小
    drawImage(img,x,y,width,height)
  3. 把源图像的一部分绘制到画布上
    drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
  1. 绘制阴影

在绘制前给下列属性设置适当的值,就可以自动为形状或路径绘制出阴影

  1. shadowColor:阴影的颜色,同css颜色格式,默认为黑色
  2. shadowOffsetX:形状或路径x轴方向的阴影偏移量,默认为0
  3. shadowOffsetY:形状或路径y轴方向的阴影偏移量,默认为0
  4. shadowBlur:模糊的像素数,默认为0,即不模糊
  1. 变换
  1. 修改变换矩阵的方法
  1. translate(x,y):将坐标原点(0,0)移动到(x,y)点
  2. rotate(angle): 围绕原点旋转图像angle弧度
  3. scale(scalex,scaley):缩放图像,在x方向乘以scalex,在y方向乘以scaley,两个参数值默认都是1.0
  4. transform(m1_1,m1_2,m2_1,m2_2,dx,dy):直接修改变换矩阵,方式是乘以如下矩阵
m1_1	m1_2	dx
m2_1	m2_2	dy
0		0		1
  1. setTransform(m1_1,m1_2,m2_1,m2_2,dx,dy):将变换矩阵重置为默认状态,然后再调用transform()
  2. 保存或恢复某些属性he变换
  1. 这些属性和变换在当前上下文中一直有效
  2. save():当时的所有设置都会进入一个栈结构,进行保存,可以保存多个
  3. restore():恢复到上一个保存设置的状态,栈结构一级一级恢复
  1. 渐变
  1. 线性渐变
  1. 创建线性渐变对象:createLinearGradient(x,y,x1,y1),接收4个参数,分别为起点(x,y)和终点(x1,y1),调用该方法后,会创建一个指定大小的渐变,并返回CanvasGradient对象的实例
  2. addColorStop(色标位置,color):指定色标,通过渐变对象调用该方法,接收两个参数,分别为色标位置和css颜色值;色标位置是一个0(开始的颜色)到1(结束的颜色)之间的数字
  3. 把fillStyle货strokeStyle的属性值设置为该渐变对象
  1. 放射渐变
  1. 创建放射渐变对象:createRadiaGradient(x,y,radius,x1,y1,radius1),接收6个参数,为开始和结束的两个圆的圆心(x,y)、(x1,y1)和半径radius、radius1;可以看成一个圆锥的效果;一般是两个同心圆
  2. 指定色标,addColorStop(),同线性渐变
  3. 把fillStyle的属性值设置为该渐变对象
  1. 渐变不会重复
  2. 例子
let gradient = ctx.createLinearGradient(30,30,70,70);
let gradient1 = ctx.createRadialGradient(55,55,10,55,55,30);
gradient.addColorStop(0,'#fff');
gradient.addColorStop(1,'#000');
ctx.fillStyle = gradient;
ctx.fillRect(30,30,50,50);
  1. 模式
  1. 模式其实就是重复的图像,可以用来填充或描边图像
  2. 创建模式对象:createPattern(img,type)
  1. 接收两个参数,要重复的图像和如何重复图像的字符串
  2. 第一个参数可以是:<img>元素、<canvas>元素、<video>元素
  3. 第二个参数可以是:repeat、repeat-x、repeat-y、no-repeat
  1. 模式对象重复从画布的原点(0,0)开始绘制
  2. 填充样式fillStyle设置为模式对象,表示在某个特定区域内显示重复图像,而不是从某个位置开始绘制重复图像
  3. 例如,重复从画布的原点(0,0)开始绘制,但是只显示从(30,30)开始的长宽为50的部分,会有一部分显示不出来
  1. 图像数据(操作图片)
  1. 将图像绘制到画布上
  2. 取得图像数据(ImageData对象的实例):
  1. getImageData(x,y,width,height)
  2. 该方法接收4个参数,要取得其数据的画面区域的开始坐标(x,y),和该区域的宽高width、height
  3. 该方法返回的对象时ImageData对象的实例,即要操作的图像数据对象
  4. ImageData有3个属性,width、height、data
  5. data属性是一个数组,每一项都保存着图像中每一个像素的数据;在data数组的每一项中,每个像素用4个元素来保存,分别表示红绿蓝和透明度的值;每个元素的值为0-255
  6. 能够访问原始图像数据,就可以操作这些数据
  1. 更改图像数据(遍历data,i每次递增4)
  2. 回写图像数据(把更改后的data写到ImageData中)
  3. 再把图像数据绘制到画布上(putImageData(imageData,x,y))
  4. 再把画布上的图形导出为base64的URL地址(toDataURL(‘image/png’))
  5. canvas图像操作不能跨域
  6. 例子
//获取原始图像
let img = document.images[0];
//创建ctx对象
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');
//在画布上绘制原始图像
ctx.drawImage(img,0,0);
//获取图像数据
let imageData = ctx.getImageData(0,0,img.width,img.height);
let data = imageData.data;
//遍历图像数据,并操作更改该数据
let red,green,blue,alpha,average;
for(let i=0;i<data.length;i+=4){
	red = data[i];
	green = data[i+1];
	blue = data[i+2];
	alpha = data[i+3]; 
	average = Math.floor((red+green+blue)/3);
	data[i] = average;
	data[i+1] = average;
	data[i+2] = average;
}
//回写改变后的data到imageData中
imageData.data = data;
//把改变后的ImageData图像数据绘制到画布上
ctx.putImageData(imageData,0,0);
//导出图像为base64的url地址
let imgurl = ctx.toDataURL('image/png');
//把url地址给图片并添加到页面
let imgnew = new Image();
imgnew.src = imgurl;
document.body.appendChild(imgnew);
  1. 合成
  1. globalAlpha:所有绘制操作的透明度,默认为0
  2. globalCompositionOperation:表示后绘制的图形怎样与先绘制的图形结合,属性值为字符串
  1. source-over(默认值):后绘制的图形在先绘制的图形的上方
  2. source-in:后绘制的与先绘制的重叠的部分可见,两者其他部分完全透明
  3. source-out:后绘制的与先绘制的重叠的部分不可见,先绘制的完全透明
  4. source-atop:后绘制的与先绘制的重叠的部分可见,先绘制的不受影响
  5. destination-over:后绘制的在先绘制的下方,只有之前透明像素下的部分可见
  6. destination-in:后绘制的在先绘制的下方,两者不重叠的部分完全透明
  7. destination-out:后绘制的擦除与先绘制的重叠的部分
  8. destination-atop:后绘制的在先绘制的下方,在两者不重叠的地方,先绘制的会变透明
  9. lighter:后绘制的与先绘制的重叠的部分的值相加,使该部分变亮
  10. copy:后绘制的完全代替与之重叠的先绘制的
  11. xor:后绘制的与先绘制的重叠的部分执行‘异或’操作
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值