构建Canvas矢量图形渲染器(一)—— 基础架构、矢量点的绘制

本课题是我今年毕业设计的课题,现在我边做边跟大家分享,希望能通过“canvas矢量图形渲染器”让大家对canvas元素和其中的性能优化有更深的理解。

1.首先说说这个矢量渲染器是什么。

canvas元素封装了很对对图形绘制的接口,但是他跟flex相比最大的区别是我们通过fill() 或是 stroke()方法绘制的图形是一张像素图片,当放大或是缩小的时候会出现模糊等各种状况。所以直接调用canvasAPI来绘制矢量图形非常不合适。

这样我们就需要设计一渲染器,里面封装了各种图形的绘制接口,并通过调用渲染器的绘制方法按照我们想发来绘制每一个矢量元素。

每一个矢量元素都是一个继承自矢量图形基类的对象,比如可以使点,线,面等。每一个图形有自己的大小和位置信息,我们依次把每个图形送入渲染器,渲染器结合自己当前的属性(缩放百分比,中心点等)就可以计算出每一个图形需要绘制的真实像素位置,之后再调用canvas的底层API实现图形的绘制。

基本的类图结构如下(在设计的过程当中可能会增加一些新的功能类):

 

构建Canvas矢量图形渲染器(一)—— 基础架构、矢量点的绘制

一些点、线、面的基本矢量元素继承自Geometry类,Geometry定义了矢量图形的形状信息。同时也是Vector类的一个属性,Vector类里面还包括矢量元素的其他信息(如id、添加时间等)。

Layer类表示了当前图层的一些基本信息,例如声明了一个图层(大小是400px * 400px),同时我在坐标为(0,0)的点放置了一个半径为50px的圆,当前的缩放为100%,视图中心点也是(0,0)则我们会得到下面的这样一张图片:

构建Canvas矢量图形渲染器(一)—— 基础架构、矢量点的绘制

    注:Layer类所表示的属性:外侧的方框代表当前的视图范围(viewBounds),坐标(0, 0)点则代表视图的中心点(center),zoom的值代表当前的缩放百分比。

          Vector类所表示的属性: 拥有一个Geometry属性表示半径为70像素的圆,且拥有一个Style属性表示填充的颜色为橙色。

下面说说Layer类,Vector类和Canvas类是如何协调工作的:

Canvas类也就是渲染器类,是本课题的核心,其中定义了各种绘制Geometry图形的方法。但是我们该如何调用他进行绘制呢?

1.我们声明一个Vector类的实例V1(他表示一个矢量图形,其形状信息保存在Geometry属性当中)。

2.我们的Layer类必然有一个接口,用于接收由Vector声明的实例V1(比如addVectors方法),当我们把所有的矢量图形都接收到Layer当中后,我们就想要在浏览器当中看到我们所创建的的矢量图形。

3.之后我们就应该请渲染器类出场了,他接收了Layer的所有矢量图形的引用、当前的缩放级别、当前的视图范围和当前的中心点,之后渲染器通过一大堆的计算就神奇的把Geometry中的属性变成了CanvasAPI中可以调用的数据。

    注:就拿上个例子来说圆的中心点是(0,0),半径是70像素,通过渲染器的一系列计算最后我们会调用“context.arc(200, 200, 70, Math.PI * 2, true); context.fill()”这两句代码。(200,200)这两个位置便是渲染器所要计算的绘制中心点,而70这个半径参数是通过70 * zoom(当前为100%)得到的。当然我们不能单单考虑这么简单的一种情况,后面会跟大家介绍这些Geometry对应的点到底是如何计算的。

2.从构建基本的几何基类、点开始。 1.geometry类。

  这个类是一个几何图形的基类。

function Geometry(){ this.id = CanvasSketch.getId("geomtry_"); } //bounds属性定义了当前Geometry外接矩形范围。 Geometry.prototype.bounds = null; //定义Geometry的id属性。 Geometry.prototype.id = null; //定义对bounds基类克隆的方法 Geometry.prototype.clone = function () { return new Geometry(); } //销毁当前的Geometry Geometry.prototype.destroy = function () { this.bounds = null; this.id = null; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgfgwp.html