janvas 概览

文章目录

理念与特点

按照 canvas 提供的 api 的开发逻辑来说,如果想绘制一个粉红色的矩形,使用的是如下方式(设 ctx 为绘图上下文):

  1. ctx.beginPath();
  2. ctx.fillStyle = "pink";
  3. ctx.rect(0, 0, 50, 50);
  4. ctx.fill();

在这个绘制过程中,我们持有的是对 ctx 的引用,直接操作的是 ctx,以过程化的思路完成了需求:开启新路径->设置粉红色->绘制矩形形状->填充矩形。

问题在于,当需求变复杂时,过程化的抽象就有些力不从心了,比如判断一个坐标点 20, 30 是否处于这个矩形内部,比如将这个矩形向右移动 50 个像素,再比如将这个矩形以中心点旋转 30 度。

根源在于,我们想操作的其实是矩形,而不是 ctx,在面向过程方式开发中,根本就不存在矩形对象,所以,janvas 将图形对象抽象了出来。

所以,以上的三个比如,以如下的代码可轻易完成需求:

new janvas.Canvas({
  container: "#app",
  methods: {
    init: function () {
      var ctx = this.$ctx; // 获取自动初始化的 ctx 对象
      var rect = new janvas.Rect(ctx, 0, 0, 50, 50, 25, 25); // 初始化矩形对象
      console.log(rect.isPointInPath(20, 30)); // 判断坐标点是否在矩形内部
      rect.getMatrix().setOffset(25, 25).setAngle(Math.PI / 6); // 给矩形添加偏移量和旋转角度
      rect.fill(); // 使矩形进行自我绘制
    }
  }
});

可以看到,使用 new 初始化这个 rect 的时候,第一个实参是 ctx,这个行为应该属于控制权反转,将本该由我们操作的绘图上下文对象 ctx 赋值给了矩形对象,而永远不再需要直接操作它了,接下来我们只需要操作 rect 对象,完成它的继承行为,如判断坐标点是否在其内部或变形操作,或它的特定行为,如设置宽高,处处均可得心应手。

Shape 简介

此类是 janvas 中所有图形的基类,它可以理解为抽象类,构造函数如下:

Shape(ctx, sx, sy, ox, oy)

接受绘图上下文 ctx 供控制反转,接着是起始绘制点 sx, sy,而 ox, oy 不是必须的,不传值会被默认设置为 0,代表了 originX 和 originY,可以理解为 css 变形中的 transform-origin,代表了变形所依据的基点位置。

虽然实例化它没有太多意义,但是所有图形都继承到了来源于它的原型链上的方法,比较重要的方法如下:

Shape.fill(fillRule) 表示图形进行填充绘制。

Shape.stroke() 表示图形进行描边绘制。

Shape.clip(fillRule) 表示图形的剪切操作,和 ctx.clip() 类似。

Shape.restore() 表示图形恢复,与剪切搭配使用。

Shape.isPointInPath(x, y) 判断坐标点是否在图形内部。

Shape.isPointInStroke(x, y) 判断坐标点是否在图形的描边上。

Shape.setStart(sx, sy) 设置图形的起始绘制点。

Shape.setOrigin(ox, oy) 设置图形变形依据的基点。

剩余的其他函数可以在 Github janvas /doc/overview.md 中看到。

Shape 不仅提供了这些基础的方法,还主要解决了变形和样式的问题,首先是变形。

变形

shape.getMatrix()

每个 janvas 中的图形继承于 Shape,都会持有一个 Matrix 供自身变形,使用 getMatrix() 可以获得此对象,此对象提供了如下四个变形可用:

  1. setSkew(skewX, skewY) 错切(不常用)
  2. setScale(scaleX, scaleY) 缩放
  3. setAngle(angle) 旋转
  4. setOffset(offsetX, offsetY) 平移

需要注意的是,除了平移,其他三个变形操作都会依据 origin 基点变形,所以如果需要达到预期变形,不要忘了指定正确的 originX, originY。

接着简介一下样式。

样式

shape.getStyle()

同持有了 Matrix 就能轻松操作图形的变形类似,所有继承于 Shape 的对象同样持有了一个 Style 对象,也就能轻松控制图形的样式了。使用 getStyle() 可以获得此对象,此对象包含如下四个方面:

  1. 全局,即透明度、组合操作和 CSS Filter;
  2. 阴影,即阴影颜色、模糊度和偏移量;
  3. 绘制,即填充和描边样式;
  4. 线型,即虚线、虚线偏移量、线宽和线条两端样式、线条连接处样式。

getMatrix().setAngle() 操作类似,比如改变上面示例中的那个矩形 rect 的线宽,可以使用 rect.getStyle().setLineWidth(4),要看到效果,只需要把 rect.fill() 改成 rect.stroke() 即可。

其实说 janvas 是浅层封装的缘由也在于此,ctx 的样式设置,全都赋能给了具体的图形,我们改变的不再是过程化的 ctx.lineWidth = 4;,而是具体图形对象的 rect.getStyle().setLineWidth(4)

DotShape & FixedShape

并不是所有图形都能用固定的参数来描述,如 Rect 矩形可以用起始绘制点和宽高来描述,但是折线段就不同,它的数据点的数量并不是固定的,所以 janvas 抽象了 DotShape 类出来。

DotShape 简介

DotShape 同样也继承于 Shape,但它主要以点来驱动,并且它保留了所有数据点的位置,可用于对具体数据点的坐标值有需求的地方,比如 双摆运动,一根线段围绕某点进行旋转,需要求得另外一点的坐标值,用继承于 DotShape 的 Polyline 就很合适。

FixedShape 简介

<canvas> 原生提供了一个实验性的功能类,叫 Path2D,它可以接收 svgpath 字符串来生成图形,FixedShape 意思是不变的图形,内部通过 Path2D 来实现绘制,本质上来源于 ctx.fill(path2d)

它同样继承于 Shape,所以可以使得毫无生气的 path 字符串,拥有全部 Shape 的功能,瞬间焕发出了活力。比如解析 SVG 字符串绘制老虎图的这个示例:Tiger

结尾

目前 janvas 的图形部分结构如下,冒号之后代表所继承的父类:

Shape              : Object                所有图形的基类
Arc                : Shape                 圆形
Sector             : Arc                   扇形
Ellipse            : Arc                   椭圆形
RegularPolygon     : Arc                   正多边形
RegularStar        : RegularPolygon        正多角星
Rect               : Shape                 矩形
Roundrect          : Rect                  圆角矩形
Image              : Rect                  图片
Text               : Shape                 文字
Line               : Shape                 线段
BezierLine         : Line                  贝塞尔曲线(二、三阶)
Edge               : Line                  特殊连线
Triangle           : Shape                 三角形
Pin                : Triangle              标记形

Dotshape           : Shape                 由数据点构成的图形
Polyline           : DotShape              折线段
Bezier             : Polyline              贝塞尔曲线(计算所有数据点)
Polygon            : Polyline              多边形
PolyRect           : Polygon               矩形(数据点驱动)
PolyArc            : Polygon               正多边形(数据点驱动)
SuperEllipse       : Polygon               超椭圆
SmoothLine         : DotShape              经过指定点的平滑曲线
Dots               : DotShape              多个圆形(数据点驱动)

FixedShape         : Shape                 不变的形状,可解析 svg path 字符串
FixedRect          : FixedShape            不变的矩形
FixedArc           : FixedShape            不变的圆形
上一篇:go入门记录


下一篇:记录一下模仿的小demo