<canvas>元素用于生成图像。它本身就像一个画布,JavaScript 通过操作它的 api,在上面生成图像。它的底层是一个个像素,基本上<canvas>是一个可以用 JavaScript 操作的位图(bitmap)。
它与 SVG 图像的区别在于,<canvas>是脚本调用各种方法生成图像,SVG 则是一个 XML 文件,通过各种子元素生成图像。
使用 Canvas API 之前,需要在网页里面新建一个<canvas>元素。
<canvas id="myCanvas" width="400" height="250">
你的浏览器不支持canvas!
</canvas>
如果浏览器不支持这个 API,就会显示<canvas>标签中间的文字:“您的浏览器不支持 Canvas”。
每个<canvas>元素都有一个对应的CanvasRenderingContext2D对象(上下文对象)。Canvas API 就定义在这个对象上面。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
上面代码中,<canvas>元素节点对象的getContext()方法,返回的就是CanvasRenderingContext2D对象。
注意,Canvas API 需要getContext方法指定参数2d,表示该<canvas>节点生成 2D 的平面图像。如果参数是webgl,就表示用于生成 3D 的立体图案,这部分属于 WebGL API。
按照用途,Canvas API 分成两大部分:绘制图形和图像处理。
Canvas 画布提供了一个作图的平面空间,该空间的每个点都有自己的坐标。原点(0, 0)位于图像左上角,x轴的正向是原点向右,y轴的正向是原点向下。
以下方法和属性用来绘制路径。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(100, 200);
上面代码只是确定了路径的形状,画布上还看不出来,因为没有颜色。所以还需要着色。
ctx.fill();
// 或者
ctx.stroke();
上面代码中,这两个方法都可以使得路径可见。fill()在路径内部填充颜色,使之变成一个实心的图形;stroke()只对路径线条着色。
这两个方法默认都是使用黑色,可以使用fillStyle和strokeStyle属性指定其他颜色。
ctx.fillStyle = "red";
ctx.fill();
// 或者
ctx.strokeStyle = "red";
ctx.stroke();
上面代码将填充和线条的颜色指定为红色。
以下的方法和属性控制线条的视觉特征。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(100, 200);
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.setLineDash([15, 5]);
ctx.stroke();
上面代码中,线条的宽度为 3,线条的末端和交点都改成圆角,并且设置为虚线。
以下方法用来绘制矩形。
上面四个方法的格式都一样,都接受四个参数,分别是矩形左上角的横坐标和纵坐标、矩形的宽和高。
CanvasRenderingContext2D.rect()方法用于绘制矩形路径。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.rect(10, 10, 100, 100);
ctx.fill();
上面代码绘制一个正方形,左上角坐标为(10, 10),宽和高都为 100。
CanvasRenderingContext2D.fillRect()用来向一个矩形区域填充颜色。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);
上面代码绘制一个绿色的正方形,左上角坐标为(10, 10),宽和高都为 100。
CanvasRenderingContext2D.strokeRect()用来绘制一个矩形区域的边框。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "green";
ctx.strokeRect(10, 10, 100, 100);
上面代码绘制一个绿色的空心正方形,左上角坐标为(10, 10),宽和高都为 100。
CanvasRenderingContext2D.clearRect()用于擦除指定矩形区域的像素颜色,等同于把早先的绘制效果都去除。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillRect(10, 10, 100, 100);
ctx.clearRect(15, 15, 90, 90);
上面代码先绘制一个 100 x 100 的正方形,然后在它的内部擦除 90 x 90 的区域,等同于形成了一个 5 像素宽度的边框。
以下方法用于绘制弧形。
CanvasRenderingContext2D.arc()主要用来绘制圆形或扇形。
// 格式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
// 实例
ctx.arc(5, 5, 5, 0, 2 * Math.PI, true);
arc()方法的x和y参数是圆心坐标,radius是半径,startAngle和endAngle则是扇形的起始角度和终止角度(以弧度表示),anticlockwise表示做图时应该逆时针画(true)还是顺时针画(false),这个参数用来控制扇形的方向(比如上半圆还是下半圆)。
下面是绘制实心圆形的例子。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(60, 60, 50, 0, Math.PI * 2, true);
ctx.fill();
上面代码绘制了一个半径 50,起始角度为 0,终止角度为 2 * PI 的完整的圆。
绘制空心半圆的例子。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.arc(100, 20, 50, 0, Math.PI, false);
ctx.stroke();
CanvasRenderingContext2D.arcTo()方法主要用来绘制圆弧,需要给出两个点的坐标,当前点与第一个点形成一条直线,第一个点与第二个点形成另一条直线,然后画出与这两根直线相切的弧线。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arcTo(50, 50, 100, 0, 25);
ctx.lineTo(100, 0);
ctx.stroke();
上面代码中,arcTo()有 5 个参数,前两个参数是第一个点的坐标,第三个参数和第四个参数是第二个点的坐标,第五个参数是半径。然后,(0, 0)与(50, 50)形成一条直线,然后(50, 50)与(100, 0)形成第二条直线。弧线就是与这两根直线相切的部分。
以下方法和属性用于绘制文本。
fillText()方法用来在指定位置绘制实心字符。
CanvasRenderingContext2D.fillText(text, x, y [, maxWidth])
该方法接受四个参数。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillText("Hello world", 50, 50);
上面代码在(50, 50)位置写入字符串Hello world。
注意,fillText()方法不支持文本断行,所有文本一定出现在一行内。如果要生成多行文本,只有调用多次fillText()方法。
strokeText()方法用来添加空心字符,它的参数与fillText()一致。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.strokeText("Hello world", 50, 50);
上面这两种方法绘制的文本,默认都是10px大小、sans-serif字体,font属性可以改变字体设置。该属性的值是一个字符串,使用 css 的font属性即可。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.font = "Bold 20px Arial";
ctx.fillText("Hello world", 50, 50);
textAlign属性用来指定文本的对齐方式。它可以取以下几个值。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.font = "Bold 20px Arial";
ctx.textAlign = "center";
ctx.fillText("Hello world", 50, 50);
direction属性指定文本的方向,默认值为inherit,表示继承<canvas>或document的设置。其他值包括ltr(从左到右)和rtl(从右到左)。
textBaseline属性指定文本的垂直位置,可以取以下值。
measureText()方法接受一个字符串作为参数,返回一个 TextMetrics 对象,可以从这个对象上面获取参数字符串的信息,目前主要是文本渲染后的宽度(width)。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var text1 = ctx.measureText("Hello world");
text.width; // 49.46
ctx.font = "Bold 20px Arial";
text2.width; // 107.78
上面代码中,10px大小的字符串Hello world,渲染后宽度为49.46。放大到20px以后,宽度为107.78。
以下方法用于设置渐变效果和图像填充效果。
createLinearGradient()方法按照给定直线,生成线性渐变的样式。
ctx.createLinearGradient(x0, y0, x1, y1);
ctx.createLinearGradient(x0, y0, x1, y1)方法接受四个参数:x0和y0是起点的横坐标和纵坐标,x1和y1是终点的横坐标和纵坐标。通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。
该方法的返回值是一个CanvasGradient对象,该对象只有一个addColorStop()方向,用来指定渐变点的颜色。addColorStop()方法接受两个参数,第一个参数是 0 到 1 之间的一个位置量,0 表示起点,1 表示终点,第二个参数是一个字符串,表示 CSS 颜色。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, "green");
gradient.addColorStop(1, "white");
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);
上面代码中,定义了渐变样式gradient以后,将这个样式指定给fillStyle属性,然后fillRect()就会生成以这个样式填充的矩形区域。
createRadialGradient()方法定义一个辐射渐变,需要指定两个圆。
ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
createRadialGradient()方法接受六个参数,x0和y0是辐射起始的圆的圆心坐标,r0是起始圆的半径,x1和y1是辐射终止的圆的圆心坐标,r1是终止圆的半径。
该方法的返回值也是一个CanvasGradient对象。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var gradient = ctx.createRadialGradient(100, 100, 50, 100, 100, 100);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "green");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 200, 200);
上面代码中,生成辐射样式以后,用这个样式填充一个矩形。
createPattern()方法定义一个图像填充样式,在指定方向上不断重复该图像,填充指定的区域。
ctx.createPattern(image, repetition);
该方法接受两个参数,第一个参数是图像数据,它可以是<img>元素,也可以是另一个<canvas>元素,或者一个表示图像的 Blob 对象。第二个参数是一个字符串,有四个可能的值,分别是repeat(双向重复)、repeat-x(水平重复)、repeat-y(垂直重复)、no-repeat(不重复)。如果第二个参数是空字符串或null,则等同于null。
该方法的返回值是一个CanvasPattern对象。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "https://example.com/pattern.png";
img.onload = function() {
var pattern = ctx.createPattern(img, "repeat");
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 400, 400);
};
上面代码中,图像加载成功以后,使用createPattern()生成图像样式,然后使用这个样式填充指定区域。
以下属性用于设置阴影。
下面是一个例子。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 5;
ctx.shadowColor = "rgba(0,0,0,0.5)";
ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);
Canvas API 允许将图像文件写入画布,做法是读取图片后,使用drawImage()方法将这张图片放上画布。
CanvasRenderingContext2D.drawImage()有三种使用格式。
ctx.drawImage(image, dx, dy);
ctx.drawImage(image, dx, dy, dWidth, dHeight);
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
各个参数的含义如下。
下面是最简单的使用场景,将图像放在画布上,两者左上角对齐。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "image.png";
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
上面代码将一个 PNG 图像放入画布。这时,图像将是原始大小,如果画布小于图像,就会只显示出图像左上角,正好等于画布大小的那一块。
如果要显示完整的图片,可以用图像的宽和高,设置成画布的宽和高。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var image = new Image(60, 45);
image.onload = drawImageActualSize;
image.src = "https://example.com/image.jpg";
function drawImageActualSize() {
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0, this.naturalWidth, this.naturalHeight);
}
上面代码中,<canvas>元素的大小设置成图像的本来大小,就能保证完整展示图像。由于图像的本来大小,只有图像加载成功以后才能拿到,因此调整画布的大小,必须放在image.onload这个监听函数里面。
以下三个方法与像素读写相关。
(1)getImageData()
CanvasRenderingContext2D.getImageData()方法用来读取<canvas>的内容,返回一个 ImageData 对象,包含了每个像素的信息。
ctx.getImageData(sx, sy, sw, sh);
getImageData()方法接受四个参数。sx和sy是读取区域的左上角坐标,sw和sh是读取区域的宽度和高度。如果想要读取整个<canvas>区域,可以写成下面这样。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
getImageData()方法返回的是一个ImageData对象。该对象有三个属性。
(2)putImageData()
CanvasRenderingContext2D.putImageData()方法将ImageData对象的像素绘制在<canvas>画布上。该方法有两种使用格式。
ctx.putImageData(imagedata, dx, dy);
ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
该方法有如下参数。
下面是将 ImageData 对象绘制到<canvas>的例子。
ctx.putImageData(imageData, 0, 0);
(3)createImageData()
CanvasRenderingContext2D.createImageData()方法用于生成一个空的ImageData对象,所有像素都是透明的黑色(即每个值都是0)。该方法有两种使用格式。
ctx.createImageData(width, height);
ctx.createImageData(imagedata);
createImageData()方法的参数如下。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var imageData = ctx.createImageData(100, 100);
上面代码中,imageData是一个 100 x 100 的像素区域,其中每个像素都是透明的黑色。
CanvasRenderingContext2D.save()方法用于将画布的当前样式保存到堆栈,相当于在内存之中产生一个样式快照。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.save();
上面代码中,save()会为画布的默认样式产生一个快照。
CanvasRenderingContext2D.restore()方法将画布的样式恢复到上一个保存的快照,如果没有已保存的快照,则不产生任何效果。
上下文环境,restore 方法用于恢复到上一次保存的上下文环境。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.save();
ctx.fillStyle = "green";
ctx.restore();
ctx.fillRect(10, 10, 100, 100);
上面代码画一个矩形。矩形的填充色本来设为绿色,但是restore()方法撤销了这个设置,将样式恢复上一次保存的状态(即默认样式),所以实际的填充色是黑色(默认颜色)。
CanvasRenderingContext2D.canvas属性指向当前CanvasRenderingContext2D对象所在的<canvas>元素。该属性只读。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.canvas === canvas; // true
以下方法用于图像变换。
(1)rotate()
CanvasRenderingContext2D.rotate()方法用于图像旋转。它接受一个弧度值作为参数,表示顺时针旋转的度数。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.rotate((45 * Math.PI) / 180);
ctx.fillRect(70, 0, 100, 30);
上面代码会显示一个顺时针倾斜 45 度的矩形。注意,rotate()方法必须在fillRect()方法之前调用,否则是不起作用的。
旋转中心点始终是画布左上角的原点。如果要更改中心点,需要使用translate()方法移动画布。
(2)scale()
CanvasRenderingContext2D.scale()方法用于缩放图像。它接受两个参数,分别是x轴方向的缩放因子和y轴方向的缩放因子。默认情况下,一个单位就是一个像素,缩放因子可以缩放单位,比如缩放因子0.5表示将大小缩小为原来的 50%,缩放因子10表示放大十倍。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.scale(10, 3);
ctx.fillRect(10, 10, 10, 10);
上面代码中,原来的矩形是 10 x 10,缩放后展示出来是 100 x 30。
如果缩放因子为 1,就表示图像没有任何缩放。如果为-1,则表示方向翻转。ctx.scale(-1, 1)为水平翻转,ctx.scale(1, -1)表示垂直翻转。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.scale(1, -2);
ctx.font = "16px serif";
ctx.fillText("Hello world!", 20, -20);
上面代码会显示一个水平倒转的、高度放大 2 倍的Hello World!。
注意,负向缩放本质是坐标翻转,所针对的坐标轴就是画布左上角原点的坐标轴。
(3)translate()
CanvasRenderingContext2D.translate()方法用于平移图像。它接受两个参数,分别是 x 轴和 y 轴移动的距离(单位像素)。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.translate(50, 50);
ctx.fillRect(0, 0, 100, 100);
(4)transform()
CanvasRenderingContext2D.transform()方法接受一个变换矩阵的六个元素作为参数,完成缩放、旋转、移动和倾斜等变形。
它的使用格式如下。
ctx.transform(a, b, c, d, e, f);
/*
a:水平缩放(默认值1,单位倍数)
b:水平倾斜(默认值0,单位弧度)
c:垂直倾斜(默认值0,单位弧度)
d:垂直缩放(默认值1,单位倍数)
e:水平位移(默认值0,单位像素)
f:垂直位移(默认值0,单位像素)
*/
下面是一个例子。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.transform(2, 0, 0, 1, 50, 50);
ctx.fillRect(0, 0, 100, 100);
上面代码中,原始图形是 100 x 100 的矩形,结果缩放成 200 x 100 的矩形,并且左上角从(0, 0)移动到(50, 50)。
注意,多个transform()方法具有叠加效果。
(5)setTransform()
CanvasRenderingContext2D.setTransform()方法取消前面的图形变换,将画布恢复到该方法指定的状态。该方法的参数与transform()方法完全一致。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.translate(50, 50);
ctx.fillRect(0, 0, 100, 100);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.fillRect(0, 0, 100, 100);
上面代码中,第一个fillRect()方法绘制的矩形,左上角从(0, 0)平移到(50, 50)。setTransform()方法取消了这个变换(已绘制的图形不受影响),将画布恢复到默认状态(变换矩形1, 0, 0, 1, 0, 0),所以第二个矩形的左上角回到(0, 0)。
除了CanvasRenderingContext2D对象提供的方法,<canvas>元素本身也有自己的方法。
<canvas>元素的toDataURL()方法,可以将 Canvas 数据转为 Data URI 格式的图像。
canvas.toDataURL(type, quality);
toDataURL()方法接受两个参数。
该方法的返回值是一个 Data URI 格式的字符串。
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
上面的代码将<canvas>元素,转化成 PNG Data URI。
var fullQuality = canvas.toDataURL("image/jpeg", 0.9);
var mediumQuality = canvas.toDataURL("image/jpeg", 0.6);
var lowQuality = canvas.toDataURL("image/jpeg", 0.3);
上面代码将<canvas>元素转成高画质、中画质、低画质三种 JPEG 图像。
HTMLCanvasElement.toBlob()方法用于将<canvas>图像转成一个 Blob 对象,默认类型是image/png。它的使用格式如下。
// 格式
canvas.toBlob(callback, mimeType, quality)
// 示例
canvas.toBlob(function (blob) {...}, 'image/jpeg', 0.95)
toBlob()方法可以接受三个参数。
注意,该方法没有返回值。
下面的例子将<canvas>图像复制成<img>图像。
var canvas = document.getElementById('myCanvas');
function blobToImg(blob) {
var newImg = document.createElement('img');
var url = URL.createObjectURL(blob);
newImg.onload = functio () {
// 使用完毕,释放 URL 对象
URL.revokeObjectURL(url);
};
newImg.src = url;
document.body.appendChild(newImg);
}
canvas.toBlob(blobToImg);
通过改变坐标,很容易在画布 Canvas 元素上产生动画效果。
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var posX = 20;
var posY = 100;
setInterval(function() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
posX += 1;
posY += 0.25;
ctx.beginPath();
ctx.fillStyle = "white";
ctx.arc(posX, posY, 10, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}, 30);
上面代码会产生一个小圆点,每隔 30 毫秒就向右下方移动的效果。setInterval()函数的一开始,之所以要将画布重新渲染黑色底色,是为了抹去上一步的小圆点。
在这个例子的基础上,通过设置圆心坐标,可以产生各种运动轨迹。下面是先上升后下降的例子。
var vx = 10;
var vy = -10;
var gravity = 1;
setInterval(function() {
posX += vx;
posY += vy;
vy += gravity;
// ...
});
上面代码中,x坐标始终增大,表示持续向右运动。y坐标先变小,然后在重力作用下,不断增大,表示先上升后下降。
通过getImageData()方法和putImageData()方法,可以处理每个像素,进而操作图像内容,因此可以改写图像。
下面是图像处理的通用写法。
if (canvas.width > 0 && canvas.height > 0) {
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
filter(imageData);
context.putImageData(imageData, 0, 0);
}
上面代码中,filter是一个处理像素的函数。以下是几种常见的filter。
(1)灰度效果
灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。
grayscale = function(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3;
}
return pixels;
};
上面代码中,d[i]是红色值,d[i+1]是绿色值,d[i+2]是蓝色值,d[i+3]是 alpha 通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以 3,再将结果写回数组。
(2)复古效果
复古效果(sepia)是将红、绿、蓝三种值,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。
sepia = function(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = r * 0.393 + g * 0.769 + b * 0.189; // red
d[i + 1] = r * 0.349 + g * 0.686 + b * 0.168; // green
d[i + 2] = r * 0.272 + g * 0.534 + b * 0.131; // blue
}
return pixels;
};
(3)红色蒙版效果
红色蒙版指的是,让图像呈现一种偏红的效果。算法是将红色通道设为红、绿、蓝三个值的平均值,而将绿色通道和蓝色通道都设为 0。
var red = function(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = (r + g + b) / 3; // 红色通道取平均值
d[i + 1] = d[i + 2] = 0; // 绿色通道和蓝色通道都设为0
}
return pixels;
};
(4)亮度效果
亮度效果(brightness)是指让图像变得更亮或更暗。算法将红色通道、绿色通道、蓝色通道,同时加上一个正值或负值。
var brightness = function(pixels, delta) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
d[i] += delta; // red
d[i + 1] += delta; // green
d[i + 2] += delta; // blue
}
return pixels;
};
(5)反转效果
反转效果(invert)是指图片呈现一种色彩颠倒的效果。算法为红、绿、蓝通道都取各自的相反值(255 - 原值)。
invert = function(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
d[i] = 255 - d[i];
d[i + 1] = 255 - d[i + 1];
d[i + 2] = 255 - d[i + 2];
}
return pixels;
};
Canvas 是H5的一部分,允许脚本语言动态渲染图像。Canvas 定义一个区域,可以由html属性定义该区域的宽高,javascript代码可以访问该区域,通过一整套完整的绘图功能(API),在网页上渲染动态效果图。
上传截图很多做法是把图像发送到后端,把裁剪后的结果发送给浏览器,这种方式会增加处理时延。用canvas提供的API实现纯前端的剪切:这里头关键有三步:显示未经处理的图片,得到裁剪区域,显示裁剪后的区域。
javascript完成图片格式转换: 通过input上传图片,使用FileReader将文件读取到内存中。将图片转换为canvas,canvas.toDataURL()方法设置为我们需要的格式,最后将canvas转换为图片。
现在因为有了离屏Canvas,你可以不用在你的主线程中绘制图像了!Canvas 是一个非常受欢迎的表现方式,同时也是WebGL的入口。它能绘制图形,图片,展示动画,甚至是处理视频内容
最近的一个客户项目中,简化的需求是绘制按照行列绘制很多个圆圈。需求看起来不难,上手就可以做,写两个for循环。,IT行业的知识更新越来越快,能够以不变应万变的人,就是拥有良好的学习力、创造力、判断力和思考力的人。这些能力会让你在变换万千的技术海洋中,屹立不倒,不被淹没。
利用canvas将网页元素生成图片并保存在本地,首先引入三个文件,createElementNS() 方法可创建带有指定命名空间的元素节点。 createElementNS(ns,name) > createElementNS() 方法与 createElement() 方法相似
随着大数据时代的来临,物联网的日益发展,原先的 SCADA 系统本身也在求新求变,从最开始的专业计算机和操作系统,到通用计算机和相关软件,再到现在基于 HTML5 Canvas 的新型组态开发,其应用的范围也从最初的电力
在写下合格粒子运动时要先清楚你的思路,不能一开始就盲目的开始写,首先先要确定思路然后在去一步步的实现,在写的过程要注意细节,要思考js有些知识是跟数学知识相关的要注意观察
canvas 画的圆不是圆,是椭圆。不要在style里指定 Canvas 的宽度,Canvas 画布的尺寸的大小和显示的大小是有很大的区别的,在 canvas 里面设置的是才是 Canvas 本身的大小。不要企图通过闭合现有路径来开始一条新路径
由于一些移动端的兼容性原因,我们某个项目需要前端将pdf转换成在移动端页面可直接观看的界面。为了方便解决,我们采用了pdf.js这个插件,该插件可以将pdf转换成canvas绘制在页面上
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!