canvas 基本知识

2018-08-03  本文已影响0人  烟森儿

什么是 canvas


canvas 是 HTML5 新定义的标签,通过使用脚本(通常是 JavaScript)绘制图形。
<canvas> 标签只是图形容器,相当于一个画布,canvas元素本身是没有绘图能力的。所有的绘制工作必须在 JavaScript 内部完成,相当于使用画笔在画布上画画。

默认情况下,<canvas> 没有边框和内容。默认是一个 300*150 的画布,所以我们创建了 <canvas> 之后要对其设置宽高。

我们可以通过html属性‘width’,‘height’来设置canvas的宽高,不可以通过 css 属性来设置宽高。因为通过 css 属性设置的宽高会使 canvas 内的图像按照 300150 时的比例放大或缩小*

getContext()


context 是一个封装了很多绘图功能的对象,我们在页面中创建一个 canvas 标签之后,首先要使用 getContext() 获取 canvas 的上下文环境,目前 getContext() 的参数只有 2d,暂时还不支持3d

getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法

canvas 元素绘制图像


canvas 创建图形有两种方式

context.fill()

fill() 方法填充当前的图像(路径)。默认颜色是黑色。在填充前要先使用 fillStyle 设置填充的颜色或者渐变,并且如果路径未关闭,那么 fill() 方法会从路径结束点到开始点之间添加一条线,以关闭该路径(正如
closePath() 一样),然后填充该路径

context.stroke()

stroke() 方法会实际地绘制出通过 moveTo()lineTo() 方法定义的路径。默认颜色是黑色。在进行图形绘制前,要设置好绘图的样式

 fillStyle()//填充的样式
strokeStyle()//边框样式
context.lineWidth()//图形边框宽度

绘制矩形

用 canvas 绘制一个矩形很简单

fillRect(x,y,width,height) // 实心矩形 
strokeRect(x,y,width,height) // 空心矩形
//html代码
<canvas id="canvas"></canvas>
//script代码
 var canvas = document.getElementById('canvas');
 var context = canvas.getContext('2d');
 context.fillRect(0, 0, 100, 100);
 context.strokeRect(120, 0, 100, 100);

显示如下:

image

canvas绘制矩形有填充颜色
我们可以看出,在没有设置颜色的情况下,默认是黑色的。

我们还可以通过设置 fillStyle 改变其填充颜色

context.fillStyle = "pink";
context.strokeStyle = "darkred";
context.fillRect(0, 0, 100, 100);
context.strokeRect(120, 0, 100, 100);

效果如下:


image

canvas绘制矩形有填充颜色

清除矩形区域

clearRect(x,y,width,height)
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
context.fillRect(0, 0, 100, 100);
context.strokeRect(120, 0, 100, 100);
context.fillStyle = "pink";
context.strokeStyle = "darkred";
context.fillRect(0, 120, 100, 100);
context.strokeRect(120, 120, 100, 100);
context.clearRect( 50,50,120,120)

效果如下:


image

清除矩形

实心圆

context.arc(x, y, radius, starAngle,endAngle, anticlockwise)

context.beginPath();
context.arc(300, 350, 100, 0, Math.PI * 2, true);
//不关闭路径路径会一直保留下去
context.closePath();
context.fillStyle = 'rgba(0,255,0,0.25)';
context.fill();

效果如下:


image

圆弧

如果不填充颜色,实心圆就是圆弧

 context.beginPath();
 context.arc(600, 350, 100, 0, Math.PI , true);
 context.strokeStyle = 'pink';
 context.closePath();
 context.stroke();

 context.beginPath();
 context.arc(300, 350, 100, 0, Math.PI , true);
 context.strokeStyle = 'red';
 //没有closePath
 context.stroke();

效果如图:


image

canvas绘制圆弧

所以说,如果第一个圆弧没有 closePath() 并且第二个圆弧没有 beginPath() 的话就是这样的效果:

image

绘制线段

 context.strokeStyle = 'pink';
 context.lineTo(100, 100);
 context.lineTo(200, 200);
 context.stroke();*/

效果如下:

image
每次lineTo后如果没有moveTo,那么下次lineTo的开始点为前一次lineTo的结束点
例如:
// 绘制片段
 context.strokeStyle = 'pink';
 context.lineTo(200, 200);
 context.lineTo(200, 100);
 context.lineTo(100,50);
 context.stroke();

效果如下:


image

我们可以使用 canvas 的线段绘制各种各样的图形,比如绘制一个六边形

var n = 0;
 var dx = 150;
 var dy = 150;
 var s = 100;
 context.beginPath();
 context.fillStyle = 'pink';
 context.strokeStyle = 'rgb(0,0,100)';
 var x = Math.sin(0); // x 的正玄值。返回值在 -1.0 到 1.0 之间;
 var y = Math.cos(0); // x 的余弦值。返回的是 -1.0 到 1.0 之间的数;
 var dig = Math.PI / 15 * 5;
 for (var i = 0; i < 6; i++) {
 var x = Math.sin(i * dig);
 var y = Math.cos(i * dig);
 context.lineTo(dx + x * s, dy + y * s);
 console.log( x ,y )
 }
 context.closePath();
 context.fill();
 context.stroke();
image

绘制 30 边形:

var n = 0;
 var dx = 150;
 var dy = 150;
 var s = 100;
 context.beginPath();
 context.fillStyle = 'pink';
 context.strokeStyle = 'rgb(0,0,100)';
 var x = Math.sin(0);
 var y = Math.cos(0);
 var dig = Math.PI / 15 * 7;
 for (var i = 0; i < 30; i++) {
 var x = Math.sin(i * dig);
 var y = Math.cos(i * dig);
 context.lineTo(dx + x * s, dy + y * s);
 console.log( x ,y )
 }
 context.closePath();
 context.fill();
 context.stroke();

效果如下:


image

线性渐变

var lg= context.createLinearGradient(xStart,yStart,xEnd,yEnd)
lg.addColorStop(offset,color)

 var g1 = context.createLinearGradient(0, 0, 0, 300);
 g1.addColorStop(0, '#E55D87'); 
 g1.addColorStop(1, '#5FC3E4');
 context.fillStyle = g1;
 context.fillRect(0, 0, 400, 300);

效果如下:


image

径向渐变

var rg=context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd)
rg.addColorStop(offset,color)

例如:

// 同心圆径向渐变
 var g1 = context.createRadialGradient(200, 150, 0, 200, 150, 200);
 g1.addColorStop(0.1, '#F09819');
 g1.addColorStop(1, '#EDDE5D');
 context.fillStyle = g1;
 context.beginPath();
 context.arc(200, 150, 100, 0, Math.PI * 2, true);
 context.closePath();
 context.fill();
image

canvas绘制同心圆径向渐变

//不同圆心的径向渐变模型
 var g1 = context.createRadialGradient(100, 150, 10, 300, 150, 80);
 g1.addColorStop(0.1, '#F09819');
 g1.addColorStop(0.8, 'red');
 g1.addColorStop(1, '#EDDE5D');

 context.fillStyle = g1;
 context.fillRect(0, 0, 300, 500);

效果图:


image

不同圆心径向渐变

图形变形

缩放

scale(x,y)

平移

translate(x,y)

图形组合

globalCompositeOperation=type
设置或返回新图像如何绘制到已有的图像上。最后的效果取决于 type 的值
type:

阴影

shadowOffsetX:设置或返回阴影距形状的水平距离(默认值为 0)
shadowOffsetY:设置或返回阴影距形状的垂直距离(默认值为 0)
shadowColor:设置或返回用于阴影的颜色
shadowBlur:设置或返回用于阴影的模糊级别(值越大越模糊)

例如:

 context.fillStyle = 'white';
 context.beginPath();
 context.arc(100,100,10,0,2 * Math.PI);
 context.shadowColor = 'white';
 context.shadowBlur = 10;
 context.fill();
 context.closePath();

我们看到的效果就是我们在开头提起的例子中的 star 粒子的效果,因为其有白色阴影的效果,所以看起来像是发光一样,效果如下图:


image

图像绘制

drawImage()
向画布上绘制图像、画布或视频

图像平铺

createPattern(image,type)
type:

图像裁剪

clip()从原始画布剪切任意形状和尺寸的区域,需要先创建裁剪区域,再绘制图像;一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。您也可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。
例如:

 // 设置剪切区域(粉色矩形)
 context.rect(0,0,500,400);
 context.fillStyle = "pink";
 context.fill();
 context.clip();

 // 在剪切区域中绘制图形(白色矩形)
 context.fillStyle = "white";
 context.fillRect(10,10,100,100);

 // 之后绘制的图形只能显示在剪切区域之内(红色矩形)
 context.fillStyle = "red";
 context.fillRect(100,100,600,600)

效果如下:可以看到我们设置的红色矩形是一个 600600 的矩形,但是显然是没有显示完的,*一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。


image

所以说我们可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。
代码如下:

context.save();
 // 设置剪切区域
 context.rect(0,0,500,400);
 context.fillStyle = "pink";
 context.fill();
 context.clip();

 // 在剪切区域中绘制图形
 context.fillStyle = "white";
 context.fillRect(10,10,100,100);

 context.restore();
 // 之后绘制的图形只能显示在剪切区域之内
 context.fillStyle = "red";
 context.fillRect(100,100,600,600)

这样就可以正常显示了:


image

绘制文字

fillText(text,x,y):绘制实心文字
strokeText():绘制文字描边(空心)
textAlign:设置或返回文本内容的当前对齐方式
textBaseline:设置或返回在绘制文本时使用的当前文本基线
font:设置或返回文本内容的当前字体属性

例如:

 context.font="40px Arial";
 context.fillText("Hello world",200,200);
 context.strokeText("Hello world",200,300)

效果如下:


image
上一篇 下一篇

猜你喜欢

热点阅读