Canvas基础知识整理

Canvas入门

Posted by Ry on December 25, 2018

Canvas

<canvas>元素

<canvas>标签只有两个属性 – width和height;同样可以利用DOM properties来设置。如果没有设置宽度和高度,canvas会初始化宽度为300像素和高度为150像素。注意,</canvas>标签不可省。

  <canvas id="tutorial" width="150" height="150"></canvas>

当然,该元素可以使用CSS来定义大小,但在绘制图像时会伸缩以适应它的框架尺寸;注意,当CSS的尺寸与画布的比例不一致,它会出现扭曲;如果绘制出来的图像是扭曲的可以尝试用width和height属性为<canvas>设置宽和高,而不是使用CSS。

渲染上下文

<canvas>元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,可以用来绘制和处理要展示的内容。 canvas提供了一个getContext()方法,用于获取渲染上下文和它的绘制功能。它只有一个参数,上下文的格式。

  var canvas = document.getElementById('tutorial') // 获取DOM对象
  var ctx = canvas.getContext('2d'); // 获取渲染上下文,上下格式为‘2d’

绘制图形

栅格

画布栅格(canvas grid)及座标空间。canvas元素默认被网格所覆盖;通常来说,网格中的一个单位相当于canvas元素中的一像素。栅格的起点为左上角(0,0),所有元素的位置都相对于原点定位。
Canvas_default_grid

绘制矩形

<canvas>只支持两种形式的图片绘制:矩形和路径(由一系列点连成的线段)。所有其他类型的图片都是通过一条或多条路径组合而成的。

三种绘制矩形的方法:

fillRect(x, y, width, height) – 绘制一个填充的矩形

strokeRect(x, y, width, height) – 绘制一个矩形的边框

clearRect(x, y, width, height) – 清除指定矩形区域,让清除部分透明

参数,x和y,表示相对于原点的坐标;width和height,表示宽度和高度

绘制路径

圆形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。

绘制图形所需步骤:
 1. 创建路径起始点;
 2. 使用画图命令去画出路径;
 3. 封闭路径;
 4. 路径生成后,通过描边或填充路径区域来渲染图形。

所需函数:
 beginPath() – 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
 closePath() – 闭合路径之后,图形绘制命令又重新指向上下文中
 stroke() – 通过线条来绘制图形轮廓  fill() – 通过填充路径的内容区域生成实心的图形

本质上,路径是由许多子路径构成的,这些子路径都是在一个列表中。调用beginPath()后,列表会清空重置,然后可以重新绘制新的图形。 注意,当前路径为空,即调用beginPath()之后,或者canvas刚建时,第一条路径构造命令通常被视为moveTo(),无论实际上是什么。因此,几乎总是要在设置路径之后专门指定你得起始位置。

闭合路径colsePath()不是必需的。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。

注意,使用fill()函数时,所有没有闭合的形状都会自动闭合,所以不需要调用colsePath()函数。但是调用stroke()时不会自动闭合。

移动笔触
 moveTo(x, y) – 将笔触移动到指定的坐标(x,y) ,即设置起点

线
 lineTo() – 绘制一条从当前位置到指定位置(x,y)的直线,即之前路径的结束点也是接下来的路径的开始点。

圆弧
 arc(x, y, radius, startAngle, endAngle, anticlockwise)  – 画一个以(x,y)为圆心的,radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按anticlockwise为方向(默认为顺时针)来生成。

 arcTo(x1, y1, x2, y2, radius)  – 根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。

参数:x,y圆心;radius,半径;startAngle,开始弧度;endAngle,结束弧度;anticlockwise,布尔值,true表示逆时针方向,默认顺时针方向。
注意,arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式:弧度 = (Math.PI/180)*角度。

二次贝赛尔曲线及三次贝塞尔曲线
quadraticCurveTo(cp1x, cp1y, x, y) – 绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。

bezierCurveTo(cplx, cply, cp2x, cp2y, x, y) – 绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

二次贝塞尔曲线只有一个控制点,三次贝赛尔曲线有两个控制点。
Canvas_curves

矩形
rect(x, y, width, height) – 绘制一个左上角坐标为(x,y),宽度为width及height为高度的矩形

Path2D对象

Path2D()
– 返回一个新的初始化Path2D对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含SVG path数据的字符串作为变量)。 new Path2D(); // new Path2D(path); // new Path2D(d); //

Path2D.addPath(path, [,transform])
添加了一条路径到当前路径(可能添加了一个变换矩阵)。

样式及颜色

色彩

fillStyle = color – 设置图形的填充颜色
strokeStyle = color – 设置图形轮廓的颜色
注意, 一旦设置了strokeStyle或者fillStyle的值,那么这个新值就会成为新绘制图形的默认值。如果需要给每个图形上不同的颜色,需要重新设置fillStyle或strokeStyle的值。

透明度

globalAlpha = transparencyValue 设置所有图形的透明度,有效值0~1,默认为1。
因为strokeStyle和fillstyle属性接受符合CSS3规范的颜色值,也可以用以下方法来实现

  ctx.fillstyle = "rgba(255, 0, 0, 0.5)";
  ctx.strokeStyle = "rgba(255, 0, 0, 0.5)"

线型 Line styles

lineWidth = value – 设置线条宽度。
lineCap = type – 设置线条末端样式type:butt,默认样式;round,圆弧(半圆);square,矩形
lineJoin = type – 设定线条与线条间接合处的样式。type:round、bevel、miter(默认)
miterLimit = value – 限制当两条线相交时交接处最大长度;交接处长度(斜接长度)指线条交接处内角顶点到外角顶点的长度。
getLineDash() – 返回一个包含当前虚线样式,长度为非负偶数的数组。
setLineDash() – 设置当前虚线样式。
lineDashOffset = value – 设置虚线样式的起始偏移量。

使用虚线
使用setLineDash()方法和lineDashOffset属性来定制虚线样式。setLineDash()方法接受一个数组,来指定线段与间隙交替;lineDashOffset属性设置起始偏移量。

渐变Gradients

createLinearGradient(x1, y1, x2, y2) – 该方法接受4个参数,表示渐变的起点(x1, y1)与终点(x2, y2)。
createRadialGradient(x1, y1, r1, x2, y2, r2) – 该方法接受6个参数,前三个定义一个以(x1, y1)为圆心,半径为r1的圆;后三个参数则定义另一个以(x2, y2)为圆心,r2为半径的圆。
创建canvasGradient对象后,可以使用addColorStop方法给它上色。
gradient.addColorStop(position, color) – 该方法接受2个参数,position必须是一个0到1之间的数值,表示渐变中的颜色所在的相对位置。color参数必须是一个有效的CSS颜色值。

图案样式Patterns

createPatterns(image,type) – 该方法接受两个参数。image可以是一个image对象的引用,或者是另一canvas对象。type必须是下面的字符串之一:repeat、repeat-x、repeat-y和no-repeat。

注意,用canvas对象作为image参数在fireFox1.5(Gecko 1.8)中是无效的;需要确认image对象是否已经装载完毕,否则图案可能效果不对。 使用image对象的onload方法来确保设置图案之前图像已经装载完毕。

阴影Shadows
shadowOffsetX = float,shadowOffsetY = float – shadowOffsetX和shadowOffsetY用来设置阴影在X轴和y轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会向上或向左延伸,正值则表示会向下或向右延伸,它们都默认为0。
shadowBlur = float – 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受矩阵变换所影响,默认为0。
shadowColor = color – 用于设定阴影颜色效果,默认是全透明的黑色。

Canvas填充规则

当使用fill(或者clip和isPointinPath)可以选择一个填充规则,该填充规则根据某处在路径的外面或里面来决定该处是否被填充。
两个可能的值:nonzero(默认值),evenodd

绘制文本

渲染文本的两种方式:
filltext(text, x, y [,maxWidth]) – 在指定的(x,y)位置绘制文本,绘制的最大宽度是可选的
strokeText(text, x, y [,maxWidth]) – 在指定的(x, y)位置绘制文本框,绘制的最大宽度是可选的

文本样式:
font = value – 当前用来绘制文本的样式,与CSS font属性相同的语法,默认的字体是10px sans-serif。
textAlign = value – 文本对齐选项。可选值:start(默认值),end,left,right,center
textBaseline = value – 基线对齐选项。可选值: top,hanging,middle,alphabetic(默认值),ideographic,bottom。
direction = value – 文本方向。可能的值包括:ltr,rtl,inherit(默认值)。

预测量文本宽度:
measureText() – 返回一个TextMetrics对象的宽度、所在像素,这些体现文本特性的属性

使用图片

获取需要绘制的图片
HTMLImageElement – 这些图片是由Image()函数构造出来的,或者任何<img>元素
HTMLVideoElement – 用一个HTML的<video>元素作为图片源,可以从视频中抓取当前帧作为一个图像
HTMLCanvasElement – 可以使用另一个<canvas>元素作为图片源
ImageBitmap – 这是一个高性能的位图,可以延迟地绘制,它可以从上述的所有源以及其他几种源中生 成。
这些源统一由CanvasImageSource类型来引用。

使用相同页面内的图片:
document.images集合
document.getElementsByTagName()
如果你知道你想使用的指定图片的id,可以使用document.getElememtById()获取这个图片

使用其他域名下的图片:
在HTMLImageElement上使用crossOrigin属性,可以请求加载其他域名上的图片。如果服务器允许跨域,不会污染canvas;反之,则会污染canvas

使用其他canvas元素:
和引用页面内的图片相似,但引入的应该是已经准备好的canvas。

由零开始创建图像:
利用一个新的HTMLImageElement对象(使用Image()构造函数)。

  var img = new Image();   // 创建一个<img>元素
  img.src = 'myImage.png'; // 设置图片源地址 

通过data:url方式嵌入图像:

  img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw=='

优点,图片即时可用,无须再到服务器兜一圈;缺点,就是图像没法缓存,图片大的话内嵌的URL数据会相当长。

使用视频帧:
使用<video>中的视频帧。

  function getMyVideo() {
    var canvas = document.getElementById('canvas');
    if(canvas.getContext){
      var ctx = canvas.getContext('2d');

      return document.getElementById('myvideo')
    }
  }

绘制图片
drawImage(image, x, y) – image是image或canvas对象,x和y是其在目标在canvas里的起始坐标。

缩放Scaling drawImage(image, x, y, width, height) – 多了两个参数:width,height,用来控制当向canvas画入时应该缩放的大小。 注意,图像可能会因为大幅度的缩放起杂点或者模糊。如果图片里面有文字,那么最好不要进行缩放。

切片Sling
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
第一个参数同上,后八个参数中,前四个参数是定义图片的切片位置和大小,后四个则是定义切片的目标显示位置和大小。

变形

状态的保存和恢复

save() – 保存画布的所有状态
restore() – save和restore方法是用来保存和恢复canvas状态的,都没有参数。

Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:

当前应用的变形(即移动,旋转和缩放,见下)
strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit,shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
当前的裁切路径(clipping path)
你可以调用任意多次 save 方法。

每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。

移动Translating
translate(x, y) – 该方法接受两个参数。x左右偏移量,y上下偏移量

旋转Rotating
rotate(angle) – 只接受一个参数,旋转的角度(angle),顺时针方向,以弧度为单位

缩放Scaling
scale(x, y) – 缩放画布的水平和垂直的单位。参数可为负,x为水平缩放因子,y为垂直缩放因子,比1小,缩放图形,比1大,放大图形。默认为1,为实际的大小。

变形
transform(m11, m12, m21, m22, dx, dy) – 将当前的变形矩阵乘上一个基于自身参数的矩阵。
如果任意一个参数是无限大,变形矩阵也必须是无限大。
参数:
 m11: 水平缩放
 m12: 水平倾斜偏移
 m21: 竖直倾斜偏移
 m22: 竖直缩放
 dx: 水平移动  dy: 竖直移动

 setTransform() – 重置当前变形矩阵为单位矩阵,然后用相同的参数调用transform方法
 resetTransform() – 重置当前变形为单位矩阵,参数同上

动画

 基本步骤: 清空canvas –> 保存canvas状态 –> 绘制动画图形 –> 恢复canvas状态
 动画操控: setInterval(function, delay),setTimeout(function, delay), requestAnimationFrame(callback)

更多详情