Canvas快速入门

Canvas快速入门

参考

< canvas> 元素

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

<canvas>元素只有两个属性,width并且height. 这些都是可选的,也可以使用属性进行设置。指定nowidthheight属性时,画布最初将是300 像素宽和150 像素高。元素可以通过CSS任意调整大小,但在渲染过程中,图像会缩放以适应其布局大小:如果 CSS 调整大小不考虑初始画布的比例,则会出现失真。

注意: 如果渲染看起来失真,可以尝试在属性中明确指定width和属性,而不是CSS。

<canvas>元素可以像任何普通图像一样设置样式(margin, border,background …)。但是,这些规则不会影响画布上的实际绘图。我们将在本教程的专门章节中看到这是如何完成的。当没有样式规则应用于画布时,它最初将是完全透明的。

渲染上下文

canvas元素创建一个固定大小的绘图表面,该表面公开一个或多个渲染上下文,用于创建和操作显示的内容。

画布最初是空白的。要显示某些内容,脚本首先需要访问渲染上下文并在其上绘制。canvas元素有一个getContext(),用于获取渲染上下文及其绘图功能。getContext()接受一个参数,即上下文的类型。对于2D图形,我们指定2d获取CanvasRenderingContext2D

const canvas = document.getElementById('tutorial');
const ctx = canvas.getContext('2d');

其中我们先获取canvas元素节点, 之后我们通过getContext()方法访问绘图的上下文。(与上述的文字描述一致)

用画布绘制形状

通过上一节我们已经设置了画布的环境同时获得了访问绘图的上下文。通过这一小节我们将学习绘制

一些基本的图形矩形、三角形、直线、圆弧和曲线。

网格

在开始绘图之前我们要先知道画布中的网格也就是坐标系

img

通常网格中的 1 个单位对应于画布上的 1 个像素。该网格的原点位于坐标 (0,0) 的左上角。所有元素都相对于该原点放置。因此,蓝色正方形左上角的位置变为距左侧 x 个像素,距顶部 y 个像素,坐标为 (x,y)。在本教程的后面,我们将看到如何将原点转换到不同的位置、旋转网格甚至缩放它,但现在我们将坚持使用默认值。

绘制矩形

看一下绘图上下文为我们提供的三个绘制矩形的函数:

  • fillRect(x,y,width,height) 绘制一个填充的矩形。
  • strokeRect(x, y,width, height) 绘制矩形轮廓。
  • clearRect(x,y,width,height) 指定矩形区域,使之完全透明。

绘制示例

function draw() {
  context.fillRect(25, 25, 100, 100);
  context.clearRect(45, 45, 60, 60);
  context.strokeRect(50, 50, 50, 50);
}
draw();

展示结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6PdN7rHm-1657305244371)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220708143849788.png)]

绘制路径

路径是点列表,由线段连接,这些线段可以具有不同的形状,弯曲的或不弯曲、不同的宽度和不同颜色。可以关闭路径,甚至是子路径。为了使用路径制作形状,我们采取了一些额外的步骤:

① 首先,创建路径

② 然后使用绘图命令绘制到路径中

③ 创建路径后,您可以描边或者填充路径来渲染它

以下有一些用于执行这些步骤的函数:

  • beginPath() 创建新的路径。一旦创建,未来的绘图命令都将被定向到路径中并用于构建路径。
  • 路径方法
    • moveTo(x,y) 将新子路径的起点移动到 (x,y) 坐标。
    • lineTo(x,y) 用直线将当前子路径中的最后一个点链接到指定的上(x,y)坐标。
    • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) 将三次贝塞尔曲线添加到当前路径(前两个坐标为控制点的坐标,最后一个是终点的坐标)
    • quadraticCurveTo(cpx, cpy, x, y) 将二次贝塞尔曲线添加到当前子路径(第一个点坐标是控制点的,后一个为终点的坐标)
    • arc(x, y, radius, startAngle, endAngle, counterclockwise) 以(x,y) 为中心,radius为半径的圆弧,路径从startAngle 到 endAngle结束,counterclockwise控制绘制方向是否为顺时针。
    • arcTo(x1, y1, x2, y2, radius) 前两个点为控制点坐标,radius是绘制的圆弧对应圆的半径。
    • ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) 绘制椭圆,与绘制圆类似
    • rect(x, y, width, height) 绘制矩形路径。
  • 绘图类型
    • closePath() 向路径添加一条直线,指向当前子路径的起点
    • stroke() 将对应的轮廓绘制出来
    • fill() 通过填充路径的内容区域绘制实心形状。
    • isPointInStroke(x, y) 检查点是否在所包含区域内

绘制基本图形

矩形在前面的示例中已经有了

线条

context.beginPath();
context.moveTo(40, 40);
context.lineTo(100, 40); 
context.lineTo(40, 100); 
context.closePath();
context.stroke();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dC8SVlAw-1657305244372)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709013539281.png)]

圆形

context.arc(100,50, 20, 0, Math.PI * 2);
context.fill();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3B0U152u-1657305244372)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709013529193.png)]

二次贝塞尔曲线

context.beginPath();
context.lineTo(100,30);
context.quadraticCurveTo(10,15,30,40)
context.stroke();

在这里插入图片描述

圆弧(arcTo)

 context.beginPath();
 context.lineTo(20, 20);
 context.arcTo(90, 130, 230, 20, 50);
 context.lineTo(230,20)
 context.stroke();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0we9nP5A-1657305394500)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709013427384.png)]

样式

可以对路径的粗细,颜色以及填充的颜色进行设置。

  context.beginPath();
  context.moveTo(40, 40);
  context.lineTo(100, 40); 
  context.lineTo(40, 100); 
  context.closePath();
  context.strokeStyle = "red"
  context.fillStyle = "skyblue"
  context.lineWidth = 5;
  context.stroke();
  context.fill();

在这里插入图片描述

绘制文本

context.font = "italic 30px 黑体";
context.fillText("hello", 50,50)

在这里插入图片描述

绘制图片

  var img = new Image();
  img.src = "./pic.png"
  // 在图形装载完毕的时候触发绘制
  img.onload = function() {
    context.drawImage(img, 20, 0, 200, 100)
  }

在这里插入图片描述

绘图状态

  context.save();
  context.fillStyle = 'green';
  context.fillRect(10, 10, 100, 100);
  context.restore();
  context.fillRect(150, 40, 100, 100);

在这里插入图片描述

可以看到我们用save方法先保存了之前的绘图状态,再在绘制第二个长方形的时候使用restore回退到之前的绘图状态,所以第二个长方形的填充颜色为black。

变形

平移

将网格的原点即坐标原点移动到指定位置。(不改变之前绘制好了的图形)

  context.fillRect(10, 10, 50, 50);
  context.translate(30, 30);   // 对坐标系进行平移
  context.fillStyle = "red";
  context.fillRect(10, 10, 50, 50);
  context.stroke();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N5EuYCju-1657305244375)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709020513230.png)]

缩放

将之后绘制的图形都缩放到x,y倍.包括设置的坐标点也会扩大对应的倍数

  context.fillRect(10, 10, 10, 10);
  context.scale(2, 2);   // 放缩
  context.fillStyle = "red";
  context.fillRect(10, 10, 10, 10);
  context.stroke();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNxSiH5G-1657305244376)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709021120568.png)]

旋转

将整个网格进行顺时针旋转操作

img

  context.arc(0, 0, 5, 0, 2 * Math.PI);
  context.fillStyle = 'blue';
  context.fill();
  context.fillStyle = 'gray';
  context.fillRect(100, 0, 80, 20);
  context.rotate(45 * Math.PI / 180);   // 进行旋转
  context.fillStyle = 'red';
  context.fillRect(100, 0, 80, 20);
  context.setTransform(1, 0, 0, 1, 0, 0);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U74dFshf-1657305244377)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709021511444.png)]

合成

属性设置绘制新形状时应用的合成操作类型。就是当元素重叠的时候可以设置重叠部分的样式。

  context.globalCompositeOperation = 'xor';
  context.fillStyle = 'blue';
  context.scale(3,3)
  context.fillRect(10, 10, 10, 10);
  context.fillStyle = 'red';
  context.fillRect(15, 15, 10, 10);

  context.globalCompositeOperation = 'luminosity';
  context.fillStyle = 'blue';
  context.fillRect(30, 10, 10, 10);
  context.fillStyle = 'red';
  context.fillRect(35, 15, 10, 10);

  context.globalCompositeOperation = 'soft-light';
  context.fillStyle = 'blue';
  context.fillRect(50, 10, 10, 10);
  context.fillStyle = 'red';
  context.fillRect(55, 15, 10, 10);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Owugp4eI-1657305244377)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709022919815.png)]

阴影

  context.shadowBlur = 20;
  context.shadowColor = "rgb(0 ,0, 0)";
  context.scale(3,3)
  context.fillRect(10, 10, 10, 10);

  context.shadowBlur = 0;
  context.shadowOffsetX = 5;
  context.shadowOffsetY = 5;
  context.shadowColor = "orange";
  context.fillRect(25, 10, 10, 10);
  context.shadowBlur = 20;
  context.shadowColor = "rgb(0 ,0, 0)";
  context.scale(3,3)
  context.fillRect(10, 10, 10, 10);

  context.shadowBlur = 0;
  context.shadowOffsetX = 5;
  context.shadowOffsetY = 5;
  context.shadowColor = "orange";
  context.fillRect(25, 10, 10, 10);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K22UAZf9-1657305244378)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220709023250166.png)]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值