本文主要记录Canvas基础知识汇总。
1、Canvas定义
<canvas>
元素是HTML5中的新元素,通过它可以在网页中绘制出所需的图形。<canvas>
标签只是图形的容器,真正绘制图形需要使用脚本来完成。通过使用Canvas
可以绘制路径,图形、字符以及添加图像。可以做出非常炫酷的各种特效效果。
兼容性:ie9+
2、Canvas基本使用
2.1 创建画布和对象
<canvas id="myCanvas" width="300" height="200"></canvas>
默认情况下,canvas没有边框,没有内容,默认是300150的画布。如果要重新设置宽高,可以直接在标签上制定宽高属性。也可以在js中制定。不可以使用CSS属性来设置,因为canvas是一个画布(可以理解是一张图片),通过CSS设置属性的宽高会使canvas中的内容按300150时的比例放大或缩小。
var canvas = document.getElementById('myCanvas');
//创建 context 对象
var ctx = canvas.getContext('2d');
Canvas 元素本身是没有绘图能力的,所有的绘制工作必须在 JavaScript 内部完成。getContext(“2d”) 对象是内建的 HTML5 对象,是获取canvas上下文的环境。它拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。所有的绘制都是使用其接口方法实现的。
2.2 绘制线条
moveTo(x,y)
:把路径移动到画布中的指定点lineTo(x,y)
:添加一个新点stroke()
:绘制线条,默认是黑色,如果需要指定样式,需要在绘制前指定。lineWidth
:指定线条的宽度strokeStyle
:指定线条的颜色setLineDash([])
:指定线条的虚线间隔
// 画线条
ctx.moveTo(150, 50);
ctx.lineTo(100, 100);
ctx.lineTo(200, 100);
ctx.lineTo(150, 50);
ctx.lineWidth = 3;
ctx.strokeStyle = "red";
ctx.setLineDash([3]);
ctx.stroke();
2.3 填充颜色
fillStyle
:指定填充的颜色fill()
:颜色填充
// 颜色填充
ctx.fillStyle = "blue";
ctx.fill();
2.4 绘制多图像
beginPath()
:通过清空子路径列表开始一个新路径closePath()
:将笔点返回到当前子路径起始点的方法
//绘制绿色的线条
ctx.beginPath();
ctx.moveTo(200, 100);
ctx.lineTo(200, 200);
ctx.lineTo(100, 200);
ctx.lineTo(100, 100);
ctx.setLineDash([0]);
ctx.strokeStyle = "green";
ctx.stroke();
canvas绘图是一种基于路径的绘图,通过绘制路径来绘制图形,路径是一系列点的集合。首先设置好路径,再进行绘制。当我们在绘制第二个图形时,第一个图形的路径又重新执行了一次,并且以最后的颜色及线条样式执行的。如果需要执行多颜色,则需要重新开始新路径。
2.5 绘制矩形
fillRect(x,y,width,height)
:绘制实心矩形strokeRect(x,y,width,height)
:绘制空心矩形clearRect(x,y,width,height)
:清空矩形- x:起始点X坐标
- y :起始点Y坐标
- width :矩形宽
- height :矩形高
// 绘制空心矩形
ctx.beginPath();
ctx.strokeStyle = "grey";
ctx.strokeRect(130, 150, 40, 50);
2.6 绘制圆形
arc(x,y,radius,startAngle,endAngle, anticlockwise)
- x:圆心的x坐标
- y:圆心的y坐标
- startAngle:开始角度
- endAngle:结束角度
- anticlockwise:是否逆时针,true是,false顺时针
// 绘制红色圆形
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(160, 180, 6, 0, 2 * Math.PI);
ctx.fill();
// 绘制白色圆形
ctx.beginPath();
ctx.fillStyle = "white";
ctx.arc(160, 180, 2, 0, 2 * Math.PI);
ctx.fill();
3、Canvas高级使用
3.1 线性渐变
createLinearGradient(xStart,yStart,xEnd,yEnd)
- xStart:渐变开始点x坐标
- yStart:渐变开始点y坐标
- xEnd:渐变结束点x坐标
- yEnd:渐变结束点y坐标
addColorStop(offset,color)
- offset:设定的颜色离渐变结束点的偏移量(0~1)
- color:绘制时要使用的颜色
// 添加渐变
var g1 = ctx.createLinearGradient(0, 0, 0, 300);
//注意,这里不是ctx
g1.addColorStop(0, '#E55D87');
g1.addColorStop(1, '#5FC3E4');
ctx.fillStyle = g1;
ctx.fillRect(0, 0, 300, 300);
3.2 径向渐变
createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd)
- xStart:发散开始圆心x坐标
- yStart:发散开始圆心y坐标
- radiusStart:发散开始圆的半径
- xEnd:发散结束圆心的x坐标
- yEnd:发散结束圆心的y坐标
- radiusEnd:发散结束圆的半径
// 同心圆径向渐变
var g2 = ctx.createRadialGradient(100, 100, 20, 120, 120, 50);
g2.addColorStop(0, 'rgba(255,255,255,.1)');
g2.addColorStop(0.9, 'rgba(255,1,136,1)');
g2.addColorStop(1, 'rgba(255,1,136,0.5)');
ctx.fillStyle = g2;
ctx.arc(120, 120, 50, 0, 2 * Math.PI);
ctx.fill();
3.3 添加阴影
shadowOffsetX
:阴影在x方向上的偏移量,默认为0shadowOffsetY
:阴影在y方向上的偏移量,默认为0shadowColor
:阴影的颜色,默认为#000000shadowBlur
:阴影的模糊度,默认为0
// 阴影
ctx.fillStyle = "#393550";
ctx.fillRect(0, 0, 300, 300);
ctx.strokeStyle = "#41339c";
ctx.shadowColor = '#81f2f4';
ctx.shadowBlur = 20;
ctx.strokeRect(10, 10, 280, 280);
3.4 绘制图像
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:在画布上放置图像的 x 坐标位置
- y:在画布上放置图像的 y 坐标位置
- width:可选。要使用的图像的宽度
- height:可选。要使用的图像的高度
3.5 图形变形
scale(x,y)
:缩放- x :x坐标轴按 x 比例缩放
- y :x坐标轴按 y 比例缩放
translate(x,y)
:平移- x :坐标原点向x轴方向平移
- y :坐标原点向y轴方向平移
rotate(angle)
:缩放- angle :坐标轴旋转x角度(角度变化模型和画圆的模型一样)
var img = new Image();
img.src = "./images/2.png";
img.onload = function () {
ctx.beginPath();
ctx.scale(0.5, 0.5);
ctx.translate(200, 150);
ctx.rotate(30 * Math.PI / 180);
ctx.drawImage(this, 10, 10, 280, 280)
}
3.6 图形组合
globalCompositeOperation
:设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上
3.7 图形平铺
createPattern(img,type)
:在指定的方向内重复指定的元素。- img:图片、视频,或者其他
- type:repeat:默认。该模式在水平和垂直方向重复
- repeat-x:该模式只在水平方向重复
- repeat-y:该模式只在垂直方向重复
- no-repeat:该模式只显示一次(不重复)
// 获取页面上已有的图片
var img = document.getElementById('img');
var g1 = ctx.createPattern(img, "repeat-x");
ctx.fillStyle = g1;
ctx.rect(0, 0, 275, 200);
ctx.fill()
3.8 图像剪切
clip()
从原始画布中剪切任意形状和尺寸,一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fillStyle = "#00b195";
ctx.fill();
ctx.clip();
ctx.fillStyle = "black";
ctx.fillRect(100, 100, 50, 50);
在canvas中可以通过 save() 方法保存裁切区之前的状态,完成裁切后再使用 restore() 方法进行状态读取。
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fillStyle = "#00b195";
ctx.fill();
// 保存裁切前的状态
ctx.save();
ctx.clip();
ctx.fillStyle = "black";
ctx.fillRect(100, 100, 50, 50);
// 释放裁切前的状态
ctx.restore();
ctx.fillStyle = "pink";
ctx.fillRect(50, 50, 50, 50);
3.9 绘制文字
font
:设置或返回文本字体属性,如font-style,font-weight,font-size等textAlign
:对齐方式设置,取值:start, end,left,right,center,默认值为starttextBaseline
:文本基线设置,取值:top,middle,alphabetic,ideographic,bottom,默认值:alphabeticfillText(text,x,y,[maxWidth])
:绘制实心文字strokeText(text,x,y,[maxWidth])
:绘制实心文字- text:显示文本
- x:文本开始的x坐标
- y:文本开始的y坐标
- maxWidth:可选,文本显示的最大宽度
ctx.font = "40px 隶书";
ctx.strokeStyle = "#00b195";
ctx.strokeText('黑玛鱼', 250, 40);
// 加了maxWidth
ctx.strokeText('黑玛鱼', 250, 100, 240);
// 加了textAlign
ctx.textAlign = "right";
ctx.fillStyle = "#409eff";
ctx.fillText('黑玛鱼', 250, 150, 240);
// 加了textBaseline
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillText('黑玛鱼', 250, 150, 240);
3.10 贝塞尔曲线
-
quadraticCurveTo(x1, y1, ex, ey)
:二次贝塞尔曲线
-
bezierCurveTo(x1, y1, x2, y2, ex, ey)
:三次贝塞尔曲线- x1: 第一个贝塞尔控制点的x坐标
- y1: 第一个贝塞尔控制点的y坐标
- x2: 第二个贝塞尔控制点的x坐标
- y2: 第二个贝塞尔控制点的y坐标
- ex: 结束点的x坐标
- ey: 结束点的y坐标