canvas 画布

01 【认识canvas】

1.概述

<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 分成两大部分:绘制图形和图像处理

 02 【canvas绘制基本图形】

 Canvas 画布提供了一个作图的平面空间,该空间的每个点都有自己的坐标。原点(0, 0)位于图像左上角,x轴的正向是原点向右,y轴的正向是原点向下。

1.绘制三角形

以下方法和属性用来绘制路径。

  • CanvasRenderingContext2D.beginPath():开始绘制路径。
  • CanvasRenderingContext2D.closePath():结束路径,返回到当前路径的起始点,会从当前点到起始点绘制一条直线。如果图形已经封闭,或者只有一个点,那么此方法不会产生任何效果。
  • CanvasRenderingContext2D.moveTo():设置路径的起点,即将一个新路径的起始点移动到(x,y)坐标。
  • CanvasRenderingContext2D.lineTo():使用直线从当前点连接到(x, y)坐标。
  • CanvasRenderingContext2D.fill():在路径内部填充颜色(默认为黑色)。
  • CanvasRenderingContext2D.stroke():路径线条着色(默认为黑色)。
  • CanvasRenderingContext2D.fillStyle:指定路径填充的颜色和样式(默认为黑色)。
  • CanvasRenderingContext2D.strokeStyle:指定路径线条的颜色和样式(默认为黑色)

/** @type {HTMLCanvasElement} */
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()只对路径线条着色。

 

 

这两个方法默认都是使用黑色,可以使用fillStylestrokeStyle属性指定其他颜色。

 ctx.fillStyle = 'red';
ctx.fill();
// 或者
ctx.strokeStyle = 'red';
ctx.stroke();

上面代码将填充和线条的颜色指定为红色。

 

 

2.绘制弧线

以下方法用于绘制弧形。

  • CanvasRenderingContext2D.arc():通过指定圆心和半径绘制弧形。
  • CanvasRenderingContext2D.arcTo():通过指定两根切线和半径绘制弧形。

CanvasRenderingContext2D.arc()主要用来绘制圆形或扇形

// 格式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)

// 实例
ctx.arc(50, 50, 30, 0, 2 * Math.PI, true)

  •  arc()方法的xy参数是圆心坐标,radius是半径,startAngleendAngle则是扇形的起始角度和终止角度(以弧度表示),
  • anticlockwise表示做图时应该逆时针画(true)还是顺时针画(false),这个参数用来控制扇形的方向(比如上半圆还是下半圆)。

 

上面代码绘制了一个半径30,起始角度为0,终止角度为 2 * PI 的完整的圆。

  • 绘制空心半圆的例子。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');

ctx.moveTo(50, 100)
ctx.arc(100, 100, 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)形成第二条直线。弧线就是与这两根直线相切的部分。

绘制一个笑脸

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');

ctx.beginPath()
ctx.arc(150, 140, 100, 0, 2 * Math.PI, false)
ctx.stroke()
ctx.closePath()

ctx.beginPath()
ctx.arc(100, 100, 10, 0, 2 * Math.PI, false)
ctx.stroke()
ctx.closePath()

ctx.beginPath()
ctx.arc(200, 100, 10, 0, 2 * Math.PI, false)
ctx.stroke()
ctx.closePath()

ctx.beginPath()
ctx.arc(150, 140, 70, 0, Math.PI, false)
ctx.stroke()
ctx.closePath()

 

 

3.绘制矩形

以下方法用来绘制矩形。

  • CanvasRenderingContext2D.rect():绘制矩形路径。
  • CanvasRenderingContext2D.fillRect():填充一个矩形。
  • CanvasRenderingContext2D.strokeRect():绘制矩形边框。
  • CanvasRenderingContext2D.clearRect():指定矩形区域的像素都变成透明。

 

上面四个方法的格式都一样,都接受四个参数,分别是矩形左上角的横坐标和纵坐标、矩形的宽和高。

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 = '#bfa';
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像素宽度的边框。

 

03 【canvas样式控制】

1.线性

以下的方法和属性控制线条的视觉特征。

  • CanvasRenderingContext2D.lineWidth:指定线条的宽度,默认为1.0。
  • CanvasRenderingContext2D.lineCap:指定线条末端的样式,有三个可能的值:butt(默认值,末端为矩形)、round(末端为圆形)、square(末端为突出的矩形,矩形宽度不变,高度为线条宽度的一半)。
  • CanvasRenderingContext2D.lineJoin:指定线段交点的样式,有三个可能的值:round(交点为扇形)、bevel(交点为三角形底边)、miter(默认值,交点为菱形)。
  • CanvasRenderingContext2D.miterLimit:指定交点菱形的长度,默认为10。该属性只在lineJoin属性的值等于miter时有效。
  • CanvasRenderingContext2D.getLineDash():返回一个数组,表示虚线里面线段和间距的长度。
  • CanvasRenderingContext2D.setLineDash():数组,用于指定虚线里面线段和间距的长度。
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,线条的末端和交点都改成圆角,并且设置为虚线。

2.渐变色

以下方法用于设置渐变效果和图像填充效果。

  • CanvasRenderingContext2D.createLinearGradient():定义线性渐变样式。
  • CanvasRenderingContext2D.createRadialGradient():定义辐射渐变样式。
  • CanvasRenderingContext2D.createPattern():定义图像填充样式。

createLinearGradient()方法按照给定直线,生成线性渐变的样式

ctx.createLinearGradient(x0, y0, x1, y1)

ctx.createLinearGradient(x0, y0, x1, y1)方法接受四个参数:x0y0是起点的横坐标和纵坐标,x1y1是终点的横坐标和纵坐标。通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。

该方法的返回值是一个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, 'pink')
gradient.addColorStop(1, 'skyblue')
ctx.fillStyle = gradient
ctx.fillRect(10, 10, 200, 100)

上面代码中,定义了渐变样式gradient以后,将这个样式指定给fillStyle属性,然后fillRect()就会生成以这个样式填充的矩形区域。

createRadialGradient()方法定义一个辐射渐变,需要指定两个圆。

ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)

 

createRadialGradient()方法接受六个参数,x0y0是辐射起始的圆的圆心坐标,r0是起始圆的半径,x1y1是辐射终止的圆的圆心坐标,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);

上面代码中,生成辐射样式以后,用这个样式填充一个矩形。

3.图像填充

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()生成图像样式,然后使用这个样式填充指定区域。

4.阴影

以下属性用于设置阴影。

  • CanvasRenderingContext2D.shadowBlur:阴影的模糊程度,默认为0
  • CanvasRenderingContext2D.shadowColor:阴影的颜色,默认为black
  • CanvasRenderingContext2D.shadowOffsetX:阴影的水平位移,默认为0
  • CanvasRenderingContext2D.shadowOffsetY:阴影的垂直位移,默认为0

下面是一个例子。

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);

04 【canvas绘制文字】

以下方法和属性用于绘制文本。

  • CanvasRenderingContext2D.fillText():在指定位置绘制实心字符。
  • CanvasRenderingContext2D.strokeText():在指定位置绘制空心字符。
  • CanvasRenderingContext2D.measureText():返回一个 TextMetrics 对象。
  • CanvasRenderingContext2D.font:指定字型大小和字体,默认值为10px sans-serif
  • CanvasRenderingContext2D.textAlign:文本的对齐方式,默认值为start
  • CanvasRenderingContext2D.direction:文本的方向,默认值为inherit
  • CanvasRenderingContext2D.textBaseline:文本的垂直位置,默认值为alphabetic

fillText()方法用来在指定位置绘制实心字符。

CanvasRenderingContext2D.fillText(text, x, y [, maxWidth])

该方法接受四个参数。

  • 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.font = 'Bold Arial'
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属性用来指定文本的对齐方式。它可以取以下几个值。

  • left:左对齐
  • right:右对齐
  • center:居中
  • start:默认值,起点对齐(从左到右的文本为左对齐,从右到左的文本为右对齐)。
  • end:结尾对齐(从左到右的文本为右对齐,从右到左的文本为左对齐)。
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属性指定文本的垂直位置,可以取以下值。

  • top:上部对齐(字母的基线是整体上移)。
  • hanging:悬挂对齐(字母的上沿在一根直线上),适用于印度文和藏文。
  • middle:中部对齐(字母的中线在一根直线上)。
  • alphabetic:默认值,表示字母位于字母表的正常位置(四线格的第三根线)。
  • ideographic:下沿对齐(字母的下沿在一根直线上),使用于东亚文字。
  • bottom:底部对齐(字母的基线下移)。对于英文字母,这个设置与ideographic没有差异。

measureText()方法接受一个字符串作为参数,返回一个 TextMetrics 对象,可以从这个对象上面获取参数字符串的信息,目前主要是文本渲染后的宽度(width)。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');

var text1 = ctx.measureText('Hello world');
text1.width // 55.14

ctx.font = 'Bold 20px Arial';
var text2 = ctx.measureText('Hello world');
text2.width // 107.78

 

上面代码中,10px大小的字符串Hello world,渲染后宽度为49.46。放大到20px以后,宽度为107.78

05 【canvas图像变换】

以下方法用于图像变换。

  • CanvasRenderingContext2D.rotate():图像旋转
  • CanvasRenderingContext2D.scale():图像缩放
  • CanvasRenderingContext2D.translate():图像平移
  • CanvasRenderingContext2D.transform():通过一个变换矩阵完成图像变换
  • CanvasRenderingContext2D.setTransform():取消前面的图像变换

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.fillRect(0, 0, 100, 100)

ctx.translate(50, 50)
ctx.fillStyle = 'red'
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)

06 【canvas图像合成】

在默认情况之下,如果在Canvas之中将某个物体(源)绘制在另一个物体(目标)之上,那么浏览器就会简单地把源特体的图像叠放在目标物体图像上面。

简单点讲,在Canvas中,把图像源和目标图像,通过Canvas中的globalCompositeOperation操作,可以得到不同的效果,比如下图:

 

 

正如上图,红苹果和黑色的圆,通过globalCompositeOperationdestination-out就变成了被咬了一口的红苹果。也就是说,在Canvas中通过图像的合成,我们可以实现一些与众不同的效果,比如我们要制作一个刮刮卡抽奖的效果。 今天我们就来了解Canvas中的图像合成怎么使用。

在Canvas中globalCompositeOperation属性的值总共有26种类型,每种类型都将前生不一样的效果,当然你可能看到效果都将不样,甚至有一些效果在浏览器中并不能正常的渲染。不过不要紧,我们简单的了解这26种类型其代表的含意以及产生的效果。

ctx.beginPath()
ctx.fillStyle = 'red'
ctx.arc(40, 100, 80, 0, Math.PI * 2, true)
ctx.fill()
ctx.closePath()

上面的代码将在Canvas画布上绘制一个半径为80px的红色圆形,在这里把它称为图像源。

ctx.beginPath()
ctx.fillStyle = 'orange'
ctx.arc(120, 100, 80, 0, Math.PI * 2, true)
ctx.fill()
ctx.closePath()

 这段代码将在Canvas画布上绘制一个半径为80px的橙色圆形,在这里把它称为图像目标。在图像源和目标图像之间设置globalCompositeOperation的值,就可以完成图像的合成操作:

ctx.beginPath()
ctx.fillStyle = 'red'
ctx.arc(40, 100, 80, 0, Math.PI * 2, true)
ctx.fill()
ctx.closePath()

ctx.globalCompositeOperation = 'source-in'

ctx.beginPath()
ctx.fillStyle = 'orange'
ctx.arc(120, 100, 80, 0, Math.PI * 2, true)
ctx.fill()
ctx.closePath()

此时得到的效果如下:

 

 

  • source-over

source-overglobalCompositeOperation属性的默认值。源图形覆盖目标图形,源图形不透明的地方显示源图形,其余显示目标图形

 

  • source-in

source-in:目标图形和源图形重叠且都不透明的部分才被绘制

  • source-out

source-out:目标图形和源图形不重叠的部分会被绘制

 

  • source-atop

source-atop:目标图形和源图形内容重叠的部分的目标图形会被绘制

 

 

  • destination-over

destination-over:目标图形和源图形内容后面的目标图形会被绘制

 

source-over默认。在目标图像上显示源图像。
source-atop在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。
source-in在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。
source-out在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。
destination-over在源图像上方显示目标图像。
destination-atop在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。
destination-in在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
destination-out在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
lighter显示源图像 + 目标图像。
copy显示源图像。忽略目标图像。
xor使用异或操作对源图像与目标图像进行组合

刮刮卡练习:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      #card {
        position: absolute;
        width: 400px;
        height: 250px;
        text-align: center;
        line-height: 250px;
      }

      #myCanvas {
        position: relative;
      }
    </style>
  </head>
  <body>
    <div id="card">谢谢惠顾</div>
    <canvas id="myCanvas" width="400" height="250"> 您的浏览器不支持 Canvas</canvas>

    <script>
      /** @type {HTMLCanvasElement} */
      var canvas = document.getElementById('myCanvas')
      var card = document.getElementById('card')
      var isDraw = false
      var ctx = canvas.getContext('2d')

      ctx.beginPath()
      ctx.fillStyle = '#ccc'
      ctx.fillRect(0, 0, 400, 250)
      ctx.closePath()

      ctx.globalCompositeOperation = 'destination-out'

      canvas.addEventListener('mousedown', () => (isDraw = true))
      canvas.addEventListener('mouseup', () => (isDraw = false))
      canvas.addEventListener('mousemove', e => {
        if (!isDraw) return
        ctx.beginPath()
        ctx.arc(e.pageX, e.pageY, 20, 0, 2 * Math.PI, true)
        ctx.fill()
        ctx.closePath()
      })

      if (Math.random() < 0.1) card.textContent = '一等奖'
    </script>
  </body>
</html>

07 【canvas图像处理】

1.绘制图片

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);

各个参数的含义如下。

  • 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 img = new Image()
img.src = './images/girl.webp'

img.onload = function () {
  ctx.drawImage(this, 0, 0, 400, 250)
}

 

 

2.图片裁剪

 

ctx.drawImage(this, 640, 0, 1280, 720, 0, 0, 400, 250)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值