了解下canvas?

栏目: Html5 · 发布时间: 5年前

内容简介:Canvas API 提供了通过 JavaScript 绘制图形的能力 。它广泛用于动画、游戏图形、数据可视化、照片处理和实时视频处理领域。本文将会简单介绍下 canvas 。文章的大部分内容来源于 MDN 的这就是一个 canvas 标签,看起来和普通的 html 标签没什么不同,重要的通过 canvas 标签我们可以获取其canvas 翻译过来是画布的意思,所以接下来我们会对照画布来介绍 canvas 的API。

Canvas API 提供了通过 JavaScript 绘制图形的能力 。它广泛用于动画、游戏图形、数据可视化、照片处理和实时视频处理领域。本文将会简单介绍下 canvas 。文章的大部分内容来源于 MDN 的 canvas 教程 ,想深入了解 canvas 的可以去看一下。

初识 canvas

// 栗子 1
<canvas id="tutorial" width="150" height="150"></canvas>

这就是一个 canvas 标签,看起来和普通的 html 标签没什么不同,重要的通过 canvas 标签我们可以获取其 渲染上下文 ,canvas 的所有API都通过这个渲染上下文暴露出来,以下讲解的 API 也都基于此上下文。

canvas 翻译过来是画布的意思,所以接下来我们会对照画布来介绍 canvas 的API。

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

绘制图形

了解下canvas?

canvas 坐标系统中,元素的左上角为坐标原点,向右下延伸坐标轴,所有图形相对于原点绘制,默认 1 网格单位对应 1 像素,比如栗子1 中的 canvas 元素就形成一个 150X150 的坐标系。 上图中的矩形坐标即为 (x, y)。

和 svg 不同,canvas 只提供了一种基本图形:矩形,不过借助路径我们可以绘制想要的任意图形。

绘制矩形

canvas 提供了三种矩形 API,我们可以通过渲染上下文获取到它们。所有 API 接受四个参数: x, y, width, height。

function draw() {  
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(45, 45, 60, 60);
    ctx.strokeRect(50, 50, 50, 50);
  }
}

fillRect 和 strokeRect 分别会 “填充” 和 “描边“ 一片矩形区域。调用它们会立即绘制到画布上。

clearRect 会像橡皮擦一样清除特定的矩形区域。

结果如图:

了解下canvas?

绘制路径

路径由一系列的点组成,通过路径的组合我们可以绘制需要的任何图形。绘制一条路径步骤如下:

  1. 通过 beginPath   创建路径,并创建一个路径缓存区,当前坐标为起点。
  2. 然后通过  绘制命令  绘制路径,将绘制的 直线、弧线等存入缓存区,从而组合成图形。
  3. 最后 closePath  会在当前坐标和起点连起一条直线(可选), 最后可以 填充 或 描边 路径。

这个绘制步骤和画画差不多,落笔、描边到填充和真实世界的心智模型是相同的。其中的重头戏就是步骤2的绘制命令:

lineTo arc [bezierCurveTo()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo) 等命令分别绘制直线、弧线和贝塞尔曲线路径。而 moveTo 命令接受 x、y 两个参数,调用其会将画笔移动到指定的 x,y 坐标。

比如这里有个稍微复杂的栗子, 绘制一个吃豆人

路径复用

在吃豆人的栗子里,我们反复调用 roundedRect 函数来生成圆角矩形, canvas 提供了路径复用的方法,这就是 Path2D ,通过 Path2d 我们可以创建路径对象,调用绘制命令、甚至合并两个路径对象。以吃豆人中的圆角矩形函数为栗,使用Path2D 后的代码:

// A utility function to draw a rectangle with rounded corners.
function roundedRect(ctx, x, y, width, height, radius) {  
  const path = new Path2D();
  path.moveTo(x, y + radius);
  path.lineTo(x, y + height - radius);
  path.arcTo(x, y + height, x + radius, y + height, radius);
  path.lineTo(x + width - radius, y + height);
  path.arcTo(x + width, y + height, x + width, y + height-radius, radius);
  path.lineTo(x + width, y + radius);
  path.arcTo(x + width, y, x + width - radius, y, radius);
  path.lineTo(x + radius, y);
  path.arcTo(x, y, x, y + radius, radius);

  ctx.stroke(path);
}

加点样式?

canvas 通过状态机来保持 画笔 和 画布的状态,我们可以通过 API 来改变画笔的状态来绘制不同样式的图形。比如通过 fillStyle 和 strokeStyle 改变填充和描边的样式,通过 lineWidth 改变画笔的尺寸等。通过 createLinearGradient [createPattern(image, type)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern) 来绘制渐变色和图片背景,这里不再赘述。

文本绘制

去看原文吧

坐标轴变换

去看原文吧

加点动画?

canvas 动画的限制在于:图形绘制结束后无法再更改图形的状态(尺寸、颜色、坐标等)。这和我们熟悉的 html 元素不一样,dom 元素在渲染后还可以进行做位移、缩放等动画。由于以上原因,在 canvas 中做动画需要遵循以下步骤:

  1. 使用 clearRect 等方法清除画布
  2. 保存 canvas 的初始状态
  3. 绘制当前动画帧,这一步你可能会修改 canvas 状态
  4. 恢复 canvas 初始状态。

这里有一个 时钟动画的栗子 ,我们将不同的图形封装为对象,绘制图形时只需要调用对象的 draw 方法,这样统一了编程模型。

class Hour {  
    constructor(ctx) {
        this.ctx = ctx;
    }
    draw() {
        this.ctx.lineWidth = 14;
        this.ctx.beginPath();
        this.ctx.moveTo(-20, 0);
        this.ctx.lineTo(80, 0);
        this.ctx.stroke();
    }
}

绘制的每一帧我们会不断更新画布的状态,为了不污染下一帧的画布状态,我们需要不断调用 saverestore 来保存和回退画布状态。

这一章简单介绍了 canvas的基本知识,下篇文章会涉及 canvas 内的事件处理、碰撞检测等内容,并利用这些实现一些炫酷的效果,敬请期待。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言深度解剖

C语言深度解剖

陈正冲 / 北京航空航天大学出版社 / 2010-7 / 29.00元

《C语言深度解剖:解开程序员面试笔试的秘密》由作者结合自身多年嵌入式c语言开发经验和平时讲解C语言的心得体会整理而成,其中有很多作者独特的见解或看法。由于并不是从头到尾讲解C语言的基础知识,所以《C语言深度解剖:解开程序员面试笔试的秘密》并不适用于C语言零基础的读者,其内容要比一般的C语言图书深得多、细致得多,其中有很多问题是各大公司的面试或笔试题。 《C语言深度解剖:解开程序员面试笔试的秘......一起来看看 《C语言深度解剖》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器