canvas
用来'替代'flash等其他用于做动画或游戏的插件的一个标签
1、可以理解为div,提供一个区域用来绘制图形
2、习惯在标签上对其大小进行设置,而不是css或js,并且标签中添加文本<canvas width='xxpx' height='xxpx'>您的浏览器不支持canvas标签,请变更支持canvas的浏览器</canvas>
原因:支持canvas标签会显示正常的绘制图形,不支持canvas标签的会输出文本
3、内部所有内容或图形需要通过js来完成
4、生成js画笔; let bi=canvas对象.getContext('2d/3d');
let bi=canvas对象.getContext(type,{attrs});
type:
'2d'、'webgl'或'experimental-webgl'、'webgl2'、'bitmaprenderer'
attrs:
alpha 如果设置为false,则表示Canvas不支持全透明或者半透明,在绘制带有透明效果的图形或者图像时候速度会更快一些。
type='webgl'时:
alpha 表示Canavs是否包含透明缓冲区。
antialias 表示是否需要抗边缘锯齿,如果设置为true,图像呈现质量会好一些,但是速度会拖慢。
depth 表示绘制缓冲区的缓冲深度至少16位。
failIfMajorPerformanceCaveat 表示如果用户的系统性能比较差,是否继续常见绘制上下文。
powerPreference 高速用户使用的客户端(如浏览器)我们现在这个WebGL上下文最合适的GPU配置是什么。支持下面关键字值:
'default' 让用户的客户端设备自己觉得那个GPU配置是最合适的。这个是此参数的默认值。
'high-performance' 渲染性能优先,通常更耗掉(如手机,平板等移动设备)。
'low-power' 省电优先,渲染性能权重可以低一些。
premultipliedAlpha 表示页面合成器将假定绘图缓冲区包含具有alpha预乘(pre-multiplied alpha)颜色。
preserveDrawingBuffer 如果值为true,则不会清除缓冲区并保留其值,直到作者清除或覆盖。
stencil 表示绘图缓冲区具有至少8位的模板缓冲区。
在屏幕外渲染Canvas画布专为WebGL设计
let offscreen = new OffscreenCanvas(256, 256);
5、全局canvas元素
HTMLCanvasElement 对应canvas标签,可以往原型上自定义属性,使得所有canvas对象都能使用
其他:HTMLDivElement 对应div标签
HTMLCanvasElement.prototype.isSomeAlphaPixel = function () {
var context = this.getContext('2d');
// 获取图片像素信息
var imageData = context.getImageData(0, 0, this.width, this.height).data;
...
};
特征
1、上屏即像素化
即画的内容无法改变,脱离文本流
2、fps
frame per second即每秒加载多少帧/画
3、差异化
根据所选绘制方式是fill还是stroke来决定是画框/环/线还是填充等,lineWidth等会设置圆环宽度
绘制方法
bi.fillStyle='style'|渐变色对象|pattern填充对象; 设置区域填充样式
bi.fill(); 开始填充
bi.strokeStyle='style'|渐变色对象|pattern; 设置边框、线条、文字样式
bi.stroke(); 开始绘制
其中:
pattern:元素可以是图片、视频,或者其他 <canvas> 元素。
(1)创建pattern
bi.createPattern(元素对象,"repeat|repeat-x|repeat-y|no-repeat");
如:
元素对象有:
HTMLImageElement,也就是<img>元素,直接把<img>元素作为纹理图案是无法控制其尺寸的
HTMLVideoElement,也就是<video>元素,例如捕获摄像头视频产生的图像信息。
HTMLCanvasElement
CanvasRenderingContext2D
ImageBitmap
ImageData
例:通过canvas来作为img的容器,使得能够控制图片尺寸,然后通过这个canvas在其他canvas中进行填充等
var canvasCreated = document.createElement('canvas'); 创建一个Canvas元素
canvasCreated.width = 50;
canvasCreated.height = 34;
canvasCreated.getContext('2d').drawImage(this, 0, 0, 50, 34);
var context = canvas.getContext('2d'); 页面上需要呈现最终纹理的Canvas上下文
var pattern = context.createPattern(canvasCreated, null); 创建纹理并填充
context.fillStyle = pattern;
context.fillRect(0, 0, 250, 167);
测试点是否在绘制路径中
ctx.rect(20,20,150,100);
ctx.isPointInPath(20,50);
画矩形:
非自带颜色的矩形:
ctx.rect(方块左上角顶点x坐标,方块左上角顶点y坐标,方块x方向边长,方块y方向边长);
ctx.fillStyle=...;
ctx.fill();
方块
bi.fillStyle=...;需在方块画上前添加,因为上屏即像素化的特点
bi.fillRect(方块左上角顶点x坐标,方块左上角顶点y坐标,方块x方向边长,方块y方向边长);
bi.clearRect(方块左上角顶点x坐标,方块左上角顶点y坐标,方块x方向边长,方块y方向边长);
方框
bi.strokeStyle=...;
bi.strokeRect(方块左上角顶点x坐标,方块左上角顶点y坐标,方块x方向边长,方块y方向边长);
渐变色:
设置区域后,渐变起始是从设置的渐变区域开始,而不是其中的图案的起始开始
直线渐变
var my_gradient=ctx.createLinearGradient(x1,y1,x2,y2); 创建一个渐变区域渲染区域内的图像(非自身直接生成图像),当有一方项的坐标全为0或相同时,则可表示方向
my_gradient.addColorStop(0,"black");
.addColorStop(介于0与1之间的值,结束时的颜色)
my_gradient.addColorStop(1,"white");
ctx.fillStyle=my_gradient;
ctx.fillRect(20,20,150,100);
径向渐变
var grd=ctx.createRadialGradient(渐变的开始圆的x坐标,
渐变的开始圆的y坐标,
开始圆的半径,
渐变的结束圆的x坐标,
渐变的结束圆的y坐标,
结束圆的半径
);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white"); 会将颜色填充满整个图形
grd.addColorStop(1,"transparent"); 使得渐变只在所给半径里
文字渐变:
ctx.font="30px Verdana";
var gradient=ctx.createLinearGradient(0,0,170,0);
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red");
ctx.strokeStyle=gradient;
ctx.strokeText("Big smile!",10,50);
设置阴影:
ctx.shadowColor="orange"; 设置阴影颜色
ctx.shadowBlur=20 设置模糊级别
ctx.shadowOffsetX=n; 设置阴影x方向偏移
ctx.shadowOffsetY=; 设置阴影y方向偏移
设置全局透明度
ctx.globalAlpha=0.2; 设置之前的绘图不受影响
设置覆盖方式(图层)
源图像=您打算放置到画布上的绘图。
目标图像=您已经放置在画布上的绘图。
ctx.globalCompositeOperation="source-over"; 默认,在目标图像上显示源图像。
source-atop 在目标图像顶部显示源图像,源图像位于目标图像之外的部分是不可见的。
source-in 在目标图像中显示源图像,只有目标图像内的源图像部分会显示,目标图像是透明的。
source-out 在目标图像之外显示源图像,只会显示目标图像之外源图像部分,目标图像是透明的。
destination-over 在源图像上方显示目标图像。
destination-atop 在源图像顶部显示目标图像,源图像之外的目标图像部分不会被显示。
destination-in 在源图像中显示目标图像,只有源图像内的目标图像部分会被显示,源图像是透明的。
destination-out 在源图像外显示目标图像,只有源图像外的目标图像部分会被显示,源图像是透明的。
lighter 显示源图像 + 目标图像。
copy 显示源图像,忽略目标图像。
xor 使用异或操作对源图像与目标图像进行组合。
矩形为目标图像
保存还原绘图状态:
只是保存save之前的状态,而不是图案效果,及restore还原后还需要重新绘图
ctx.save() 保存当前Canvas画布状态并放在栈的最上面,保存的状态有
当前矩阵变换。参见transform()等。
当前剪裁区域。参见clip()。
当前虚线设置。参见setLineDash()。
以及下面这些属性的值:strokeStyle,fillStyle,globalAlpha,lineWidth,lineCap,lineJoin,miterLimit,lineDashOffset,shadowOffsetX,shadowOffsetY,shadowBlur,shadowColor,globalCompositeOperation,font,textAlign,textBaseline。
ctx.store() 依次取出
例:
context.fillStyle = 'red';
context.fillRect(20, 20, 100, 60);
context.shadowColor='blue'
context.shadowBlur=20
context.save();
context.restore();
context.fillRect(180, 60, 100, 60);
代码示例:
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.canvas{
border:solid 2px black;
}
</style>
</head>
<body>
<canvas width="300px" height="200px" class='canvas'>您的浏览器不支持canvas标签,请变更支持canvas的浏览器</canvas>
<script>
var canvas=document.querySelector('.canvas');
var bi=canvas.getContext('2d');
var num=20;
var fx=1;
var timer=setInterval(function(){
bi.fillStyle='pink';
if(num>=canvas.width-50)
{
fx=0;
}else if(num<=0){
fx=1;
}
if(fx==1){
console.log(fx,':'+num);
bi.clearRect(num,10,50,50);
bi.fillRect(++num,10,50,50);
}else{
bi.clearRect(0,0,300,200);
bi.fillRect(--num,10,50,50);
}
},25) //fps=40;
</script>
</body>
</html>