这是我参与「第四届青训营 」笔记创作活动的第10天
(使用 SVG path data 创建一个 Path2D 路径未完结,在path2D板块)
Canvas API 提供了<canvas>元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
Canvas API 主要聚焦于 2D 图形。而同样使用<canvas>元素的 WebGL API 则用于绘制硬件加速的 2D 和 3D 图形。
Canvas 的默认大小为 300 像素×150 像素(宽×高,像素的单位是 px)。但是,可以使用 HTML 的高度和宽度属性来自定义 Canvas 的尺寸。为了在 Canvas 上绘制图形,使用一个 JavaScript 上下文对象,它能动态创建图像
Canvas接口:
HTMLCanvasElementCanvasRenderingContext2DCanvasGradientCanvasImageSourceCanvasPatternImageBitmapImageDataRenderingContextTextMetricsOffscreenCanvasPath2DImageBitmapRenderingContext
<canvas> 标签只有两个属性—— width和height。
渲染上下文:
canvas 起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。<canvas> 元素有一个叫做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()接受一个参数,即上下文的类型。对于 2D 图像而言,可以使用 CanvasRenderingContext2D。
var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
模板骨架(显示为一个2D正方形):
<html>
<head>
<title>Canvas tutorial</title>
<script type="text/javascript">
function draw(){
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
}
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
</head>
<body onload="draw();">
<canvas id="tutorial" width="150" height="150"></canvas>
</body>
</html>
绘制图形
只支持两种形式的图形绘制:矩形和路径(由一系列点连成的线段)。所有其他类型的图形都是通过一条或者多条路径组合而成的
绘制矩形:
-
fillRect(x, y, width, height)绘制一个填充的矩形 -
strokeRect(x, y, width, height)绘制一个矩形的边框 -
clearRect(x, y, width, height)清除指定矩形区域,让清除部分完全透明。
x 与 y 指定了在 canvas 画布上所绘制的矩形的左上角(相对于原点)的坐标。width 和 height 设置矩形的尺寸。
绘制路径:
路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。
基础:
lineWidth:线段宽度beginPath()moveTo(x, y)lineTo(x, y)closePath()stroke():通过线条来绘制图形轮廓。fill()通过填充路径的内容区域生成实心的图形。arc(x, y, radius, startAngle, endAngle, anticlockwise)画一个以(x,y)为圆心的以 radius 为半径的圆弧(圆),从 startAngle 开始到 endAngle (用弧度表示,弧度=(Math.PI/180)×角度。)结束,按照 anticlockwise 给定的方向(默认为顺时针)来生成,为 true 时,是逆时针方向,否则顺时针方向。arcTo(x1, y1, x2, y2, radius)根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。
方法
绘制矩形位图
-
CanvasRenderingContext2D.clearRect()设置指定矩形区域内(以 点 (x, y) 为起点,范围是*(width, height)* )所有像素变成透明,并擦除之前绘制的所有内容。 -
CanvasRenderingContext2D.fillRect()绘制填充矩形,矩形的起点在 (x, y) 位置,矩形的尺寸是 width 和 height 。 -
CanvasRenderingContext2D.strokeRect()在 canvas 中,使用当前的笔触样式,描绘一个起点在 (x, y) 、宽度为 w 、高度为 h 的矩形。
绘制文本
-
CanvasRenderingContext2D.fillText()在 (x,y) 位置绘制(填充)文本。 -
CanvasRenderingContext2D.strokeText()在 (x,y) 位置绘制(描边)文本。
线型
-
CanvasRenderingContext2D.lineWidth线的宽度。默认1.0 -
CanvasRenderingContext2D.lineCap线末端的类型。允许的值:butt(默认),round,square. -
CanvasRenderingContext2D.lineJoin定义两线相交拐点的类型。允许的值:round,bevel,miter(默认)。 -
CanvasRenderingContext2D.miterLimit斜接面限制比例。默认10。 -
CanvasRenderingContext2D.getLineDash()返回当前线段样式的数组,数组包含一组数量为偶数的非负数数字。 -
CanvasRenderingContext2D.setLineDash()设置当前的线段样式。 -
CanvasRenderingContext2D.lineDashOffset描述在哪里开始绘制线段。
文本样式
-
CanvasRenderingContext2D.font字体设置。默认值10px sans-serif。 -
CanvasRenderingContext2D.textAlign文本对齐设置。允许的值:start(默认),end,left,right或center. -
CanvasRenderingContext2D.textBaseline基线对齐设置。允许的值:top,hanging,middle,alphabetic(默认),ideographic,bottom. -
CanvasRenderingContext2D.direction文本的方向。 允许的值:ltr, rtl,inherit(默认).
填充和描边样式
-
CanvasRenderingContext2D.fillStyle图形内部的颜色和样式。默认#000(黑色). -
CanvasRenderingContext2D.strokeStyle图形边线的颜色和样式。 默认#000(黑色).
渐变和图案
-
CanvasRenderingContext2D.createLinearGradient()创建一个沿着参数坐标指定的线的线性渐变。 -
CanvasRenderingContext2D.createRadialGradient()创建一个沿着参数坐标指定的线的放射性性渐变。 -
CanvasRenderingContext2D.createPattern()使用指定的图片 (aCanvasImageSource) 创建图案。通过 repetition 变量指定的方向上重复源图片。此方法返回CanvasPattern对象。
阴影
-
CanvasRenderingContext2D.shadowBlur描述模糊效果。默认0 -
CanvasRenderingContext2D.shadowColor阴影的颜色。 默认 fully-transparent black. -
[
CanvasRenderingContext2D.shadowOffsetX](developer.mozilla.org/zh-CN/docs/… 0. -
CanvasRenderingContext2D.shadowOffsetY阴影垂直方向的偏移量。默认 0.
路径
-
CanvasRenderingContext2D.beginPath()清空子路径列表开始一个新的路径。当你想创建一个新的路径时,调用此方法。 -
CanvasRenderingContext2D.closePath()使笔点返回到当前子路径的起始点。它尝试从当前点到起始点绘制一条直线。如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。 -
CanvasRenderingContext2D.moveTo()将一个新的子路径的起始点移动到 (x,y) 坐标。 -
CanvasRenderingContext2D.lineTo()使用直线连接子路径的最后的点到 x,y 坐标。 -
CanvasRenderingContext2D.bezierCurveTo()添加一个 3 次贝赛尔曲线路径。该方法需要三个点。 第一、第二个点是控制点,第三个点是结束点。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用moveTo()进行修改。 -
CanvasRenderingContext2D.quadraticCurveTo()添加一个 2 次贝赛尔曲线路径。 -
CanvasRenderingContext2D.arc()绘制一段圆弧路径, 圆弧路径的圆心在 (x, y) 位置,半径为 r ,根据anticlockwise (默认为顺时针)指定的方向从 startAngle 开始绘制,到 endAngle 结束。 -
CanvasRenderingContext2D.arcTo()根据控制点和半径绘制圆弧路径,使用当前的描点 (前一个 moveTo 或 lineTo 等函数的止点)。根据当前描点与给定的控制点 1 连接的直线,和控制点 1 与控制点 2 连接的直线,作为使用指定半径的圆的切线,画出两条切线之间的弧线路径。 -
CanvasRenderingContext2D.ellipse()添加一个椭圆路径,椭圆的圆心在(x,y)位置,半径分别是radiusX 和 radiusY ,按照anticlockwise (默认顺时针)指定的方向,从 startAngle 开始绘制,到 endAngle 结束。 -
CanvasRenderingContext2D.rect()创建一个矩形路径,矩形的起点位置是 (x, y) ,尺寸为 width 和 height。
绘制路径
-
CanvasRenderingContext2D.fill()使用当前的样式填充子路径。 -
CanvasRenderingContext2D.stroke()使用当前的样式描边子路径。 -
CanvasRenderingContext2D.drawFocusIfNeeded()如果给定的元素获取了焦点,那么此方法会在当前的路径绘制一个焦点。 -
CanvasRenderingContext2D.scrollPathIntoView()将当前或给定的路径滚动到窗口。 -
CanvasRenderingContext2D.clip()从当前路径创建一个剪切路径。在 clip() 调用之后,绘制的所有信息只会出现在剪切路径内部。例如:参见 Canvas 教程中的 剪切路径 。 -
CanvasRenderingContext2D.isPointInPath()判断当前路径是否包含检测点。 -
CanvasRenderingContext2D.isPointInStroke()判断检测点是否在路径的描边线上。
变换
在 CanvasRenderingContext2D 渲染背景中的对象会有一个当前的变换矩阵,一些方法可以对其进行控制。当创建当前的默认路径,绘制文本、图形和Path2D对象的时候,会应用此变换矩阵。下面列出的方法保持历史和兼容性的原因,是为了SVGMatrix对象现在能够应用于大部分 API ,将来会被替换。
-
CanvasRenderingContext2D.currentTransform当前的变换矩阵 (SVGMatrix对象)。 -
CanvasRenderingContext2D.rotate()在变换矩阵中增加旋转,角度变量表示一个顺时针旋转角度并且用弧度表示。 -
CanvasRenderingContext2D.scale()根据 x 水平方向和 y 垂直方向,为 canvas 单位添加缩放变换。 -
CanvasRenderingContext2D.translate()通过在网格中移动 canvas 和 canvas 原点 x 水平方向、原点 y 垂直方向,添加平移变换 -
CanvasRenderingContext2D.transform()使用方法参数描述的矩阵多次叠加当前的变换矩阵。 -
CanvasRenderingContext2D.setTransform()重新设置当前的变换为单位矩阵,并使用同样的变量调用 transform() 方法。 -
CanvasRenderingContext2D.resetTransform()使用单位矩阵重新设置当前的变换。
合成
-
CanvasRenderingContext2D.globalAlpha在合成到 canvas 之前,设置图形和图像透明度的值。默认1.0(不透明)。 -
CanvasRenderingContext2D.globalCompositeOperation通过globalAlpha应用,设置如何在已经存在的位图上绘制图形和图像。
绘制图像
CanvasRenderingContext2D.drawImage()绘制指定的图片。该方法有多种格式,提供了很大的使用灵活性。
像素控制
参见 ImageData 对象。
-
CanvasRenderingContext2D.createImageData()使用指定的尺寸,创建一个新的、空白的ImageData对象。所有的像素在新对象中都是透明的。 -
CanvasRenderingContext2D.getImageData()返回一个ImageData对象,用来描述 canvas 区域隐含的像素数据,这个区域通过矩形表示,起始点为*(sx, sy)、宽为sw、高为sh*。 -
CanvasRenderingContext2D.putImageData()将数据从已有的ImageData绘制到位图上。 如果提供了脏矩形,只能绘制矩形的像素。
图像平滑
CanvasRenderingContext2D.imageSmoothingEnabled图像平滑的方式;如果禁用,缩放时,图像不会被平滑处理。
canvas 状态
CanvasRenderingContext2D 渲染环境包含了多种绘图的样式状态(属性有线的样式、填充样式、阴影样式、文本样式)。下面的方法会帮助你使用这些状态:
-
CanvasRenderingContext2D.save()使用栈保存当前的绘画样式状态,你可以使用 restore() 恢复任何改变。 -
CanvasRenderingContext2D.restore()恢复到最近的绘制样式状态,此状态是通过 save() 保存到”状态栈“中最新的元素。 -
CanvasRenderingContext2D.canvas对HTMLCanvasElement只读的反向引用。如果和<canvas>元素没有联系,可能为null。
点击区域
-
CanvasRenderingContext2D.addHitRegion()给 canvas 添加点击区域。 -
[
CanvasRenderingContext2D.removeHitRegion()]从 canvas 中删除指定id的点击区域。 -
[
CanvasRenderingContext2D.clearHitRegions()]从 canvas 中删除所有的点击区域。
二次贝塞尔曲线及三次贝塞尔曲线
用来绘制复杂有规律的图形
-
quadraticCurveTo(cp1x, cp1y, x, y)绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。 -
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
绘制矩形
rect(x, y, width, height)绘制一个左上角坐标为(x,y),宽高为 width 以及 height 的矩形。
Path2D对象
会返回一个新初始化的 Path2D 对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含 SVG path 数据的字符串作为变量),可选参数有- path (当调用另一个 Path2D 对象时,会创建一个 path 变量的拷贝)和 d (当调用 SVG path 数据构成的字符串时,会根据描述创建一个新的路径)
Path2D.addPath(path [, transform])添加了一条路径到当前路径(可能添加了一个变换矩阵)
new Path2D(); // 空的 Path 对象
new Path2D(path); // 克隆 Path 对象
new Path2D(d); // 从 SVG 建立 Path 对象
例如
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var path1 = new Path2D();
path1.rect(10, 10, 100,100);
var path2 = new Path2D(path1);
path2.moveTo(220, 60);
path2.arc(170, 60, 50, 0, 2 * Math.PI);
ctx.stroke(path2);
使用SVG路径
使用 SVG path data 创建一个 Path2D 路径
使用样式和颜色
色彩
-
fillStyle = color设置图形的填充颜色。 -
strokeStyle = color设置图形轮廓的颜色。
color 可以是表示 CSS 颜色值的字符串,渐变对象或者图案对象
透明度
globalAlpha = transparencyValue这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0(完全透明)到 1.0(完全不透明),默认是 1.0,从设置透明度往下的所有都会被设置成该透明度。但使用符合 CSS 3 规范的颜色值rgba更好
线型
-
lineWidth = value设置线条宽度。 -
lineCap = type设置线条末端样式,butt,round和square。默认是butt。。 -
lineJoin = type设定线条与线条间接合处的样式,round,bevel和miter。默认是miter。 -
miterLimit = value限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。 -
getLineDash()返回一个包含当前虚线样式,长度为非负偶数的数组。 -
setLineDash(segments)设置当前虚线样式,用setLineDash方法和lineDashOffset属性来制定虚线样式。setLineDash方法接受一个数组,来指定线段与间隙的交替;lineDashOffset属性设置起始偏移量。。 -
lineDashOffset = value设置虚线样式的起始偏移量。
渐变
-
createLinearGradient(x1, y1, x2, y2)createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。 -
createRadialGradient(x1, y1, r1, x2, y2, r2)createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。 -
gradient.addColorStop(position, color)addColorStop 方法接受 2 个参数,position参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。color参数必须是一个有效的 CSS 颜色值(如 #FFF,rgba(0,0,0,1),等等)
图案样式
createPattern(image, type)该方法接受两个参数。Image 可以是一个Image对象的引用,或者另一个 canvas 对象。Type必须是下面的字符串值之一:repeat,repeat-x,repeat-y和no-repeat
var img = new Image();
img.src = 'someimage.png';
var ptrn = ctx.createPattern(img,'repeat');
阴影
-
shadowOffsetX = floatshadowOffsetX和shadowOffsetY用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为0。 -
shadowOffsetY = floatshadowOffsetX 和shadowOffsetY用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为0。 -
shadowBlur = floatshadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为0。 -
shadowColor = colorshadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。
绘制文本
-
fillText(text, x, y [, maxWidth])在指定的 (x,y) 位置填充指定的文本,绘制的最大宽度是可选的。 -
strokeText(text, x, y [, maxWidth])在指定的 (x,y) 位置绘制文本边框,绘制的最大宽度是可选的。 -
font = value当前我们用来绘制文本的样式。这个字符串使用和 CSSfont属性相同的语法。默认的字体是10px sans-serif。 -
textAlign = value文本对齐选项。可选的值包括:start,end,left,rightorcenter. 默认值是start。 -
textBaseline = value基线对齐选项。可选的值包括:top,hanging,middle,alphabetic,ideographic,bottom。默认值是alphabetic。 -
direction = value-measureText()将返回一个TextMetrics对象的宽度、所在像素,这些体现文本特性的属性。文本方向。可能的值包括:ltr,rtl,inherit。默认值是inherit。 -
measureText()将返回一个TextMetrics对象的宽度、所在像素,这些体现文本特性的属性。
使用图像
-
HTMLImageElement这些图片是由Image()函数构造出来的,或者任何的<img>元素 -
HTMLVideoElement用一个 HTML 的<video>元素作为你的图片源,可以从视频中抓取当前帧作为一个图像 -
HTMLCanvasElement可以使用另一个<canvas>元素作为你的图片源。 -
ImageBitmap这是一个高性能的位图,可以低延迟地绘制,它可以从上述的所有源以及其它几种源中生成。
在 HTMLImageElement上使用crossOrigin (en-US)属性,你可以请求加载其它域名上的图片。如果图片的服务器允许跨域访问这个图片,那么你可以使用这个图片而不污染 canvas,否则,使用这个图片将会污染 canvas。
-
drawImage(image, x, y)其中image是 image 或者 canvas 对象,x和y 是其在目标 canvas 里的起始坐标。 -
drawImage(image, x, y, width, height)缩放,这个方法多了 2 个参数:width和height,这两个参数用来控制 当向 canvas 画入时应该缩放的大小
通过onload触发:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function(){
for (var i=0;i<4;i++){
for (var j=0;j<3;j++){
ctx.drawImage(img,j*50,i*38,50,38);
}
}
};
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
}
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)切片,第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。其它 8 个参数前 4 个是定义图像源的切片位置和大小,后 4 个则是定义切片的目标显示位置和大小。
过度缩放图像可能会导致图像模糊或像素化。您可以通过使用绘图环境的imageSmoothingEnabled属性来控制是否在缩放图像时使用平滑算法。默认值为true,即启用平滑缩放。禁用此功能:
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
变形
-
save()保存画布 (canvas) 的所有状态 -
restore()save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数 -
translate(x, y)偏移,接受两个参数。*x *是左右偏移量,y 是上下偏移量 -
rotate(angle)旋转,只接受一个参数:旋转的角度 (angle),它是顺时针方向的,以弧度为单位的值。 旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到translate方法。 -
scale(x, y)缩放,scale方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比 1 小,会缩小图形,如果比 1 大会放大图形。默认值为 1,为实际大小。 -
transform(a, b, c, d, e, f)变形,这个方法是将当前的变形矩阵乘上一个基于自身参数的矩阵
a (m11)水平方向的缩放
b(m12)竖直方向的倾斜偏移
c(m21)水平方向的倾斜偏移
d(m22)竖直方向的缩放
e(dx)水平方向的移动
f(dy)竖直方向的移动
-
setTransform(a, b, c, d, e, f)这个方法会将当前的变形矩阵重置为单位矩阵,然后用相同的参数调用transform方法。如果任意一个参数是无限大,那么变形矩阵也必须被标记为无限大,否则会抛出异常。从根本上来说,该方法是取消了当前变形,然后设置为指定的变形,一步完成。 -
resetTransform()重置当前变形为单位矩阵,它和调用以下语句是一样的:ctx.setTransform(1, 0, 0, 1, 0, 0);
组合
globalCompositeOperation = type这个属性设定了在画新图形时采用的遮盖策略,其值是一个标识 12 种遮盖方式的字符串,source-over(这是默认设置,并在现有画布上下文之上绘制新图形)source-in(新图形只在新图形和目标画布重叠的地方绘制。其他的都是透明的)source-out(在不与现有画布内容重叠的地方绘制新图形)source-atop(新图形只在与现有画布内容重叠的地方绘制)destination-over(在现有的画布内容后面绘制新的图形)destination-in(现有的画布内容保持在新图形和现有画布内容重叠的位置。其他的都是透明的)destination-out(现有内容保持在新图形不重叠的地方)destination-atop(现有的画布只保留与新图形重叠的部分,新的图形是在画布内容后面绘制的)lighter(两个重叠图形的颜色是通过颜色值相加来确定的)copy(只显示新图形)xor(图像中,那些重叠和正常绘制之外的其他地方是透明的)multiply(将顶层像素与底层相应像素相乘,结果是一幅更黑暗的图片)screen(像素被倒转,相乘,再倒转,结果是一幅更明亮的图片)overlay(multiply 和 screen 的结合,原本暗的地方更暗,原本亮的地方更亮)darken(保留两个图层中最暗的像素)lighten(保留两个图层中最亮的像素)color-dodge(将底层除以顶层的反置)color-burn(将反置的底层除以顶层,然后将结果反过来)hard-light(屏幕相乘(A combination of multiply and screen)类似于叠加,但上下图层互换了)soft-light(用顶层减去底层或者相反来得到一个正值)difference(一个柔和版本的强光(hard-light)。纯黑或纯白不会导致纯黑或纯白)exclusion(和 difference 相似,但对比度较低)hue(保留了底层的亮度(luma)和色度(chroma),同时采用了顶层的色调(hue)saturation(保留底层的亮度(luma)和色调(hue),同时采用顶层的色度(chroma))color(保留了底层的亮度(luma),同时采用了顶层的色调 (hue) 和色度 (chroma))luminosity(保持底层的色调(hue)和色度(chroma),同时采用顶层的亮度(luma))
剪裁
clip()将当前正在构建的路径转换为当前的裁剪路径。
基本动画
步骤:清空canvas、保存canvas状态、绘制动画图形、恢复canvas状态
动画示例 时钟:
function clock(){
var now = new Date();
var ctx = document.getElementById('canvas').getContext('2d');
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI/2);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
// Hour marks
ctx.save();
for (var i=0;i<12;i++){
ctx.beginPath();
ctx.rotate(Math.PI/6);
ctx.moveTo(100,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.restore();
// Minute marks
ctx.save();
ctx.lineWidth = 5;
for (i=0;i<60;i++){
if (i%5!=0) {
ctx.beginPath();
ctx.moveTo(117,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.rotate(Math.PI/30);
}
ctx.restore();
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr>=12 ? hr-12 : hr;
ctx.fillStyle = "black";
// write Hours
ctx.save();
ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// write Minutes
ctx.save();
ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(112,0);
ctx.stroke();
ctx.restore();
// Write seconds
ctx.save();
ctx.rotate(sec * Math.PI/30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(83,0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.fill();
ctx.beginPath();
ctx.arc(95,0,10,0,Math.PI*2,true);
ctx.stroke();
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.arc(0,0,3,0,Math.PI*2,true);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#325FA2';
ctx.arc(0,0,142,0,Math.PI*2,true);
ctx.stroke();
ctx.restore();
window.requestAnimationFrame(clock);
}
window.requestAnimationFrame(clock);
高级动画
结合js编程,示例小球
像素操作
ImageData对象中存储着 canvas 对象真实的像素数据,它包含以下几个只读属性:
-
width图片宽度,单位是像素 -
height图片高度,单位是像素 -
dataUint8ClampedArray类型的一维数组,包含着 RGBA 格式的整型数据,范围在 0 至 255 之间,每个像素用 4 个 1bytes 值 (按照红,绿,蓝和透明值的顺序; 这就是"RGBA"格式) 例如,要读取图片中位于第 50 行,第 200 列的像素的蓝色部份
blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];
根据行、列读取某像素点的 R/G/B/A 值的公式:
imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 0/1/2/3];
创建一个ImageData对象
var myImageData = ctx.createImageData(width, height);
或
var myImageData = ctx.createImageData(anotherImageData);
得到场景像素数据
getImageData()
var myImageData = ctx.getImageData(left, top, width, height);
写入场景像素数据
putImageData()
ctx.putImageData(myImageData, dx, dy);
dx 和 dy 参数表示希望在场景内左上角绘制的像素数据所得到的设备坐标。
缩放和反锯齿
保存图片
-
canvas.toDataURL('image/png')默认设定。创建一个 PNG 图片,返回的图片分辨率是 96dpi。 -
canvas.toDataURL('image/jpeg', quality)创建一个 JPG 图片。你可以有选择地提供从 0 到 1 的品质量,1 表示最好品质,0 基本不被辨析但有比较小的文件大小。 -
canvas.toBlob(callback, type, encoderOptions)这个创建了一个在画布中的代表图片的 Blob 对像。