# Kity 2.0 API 更新点

<!-- MarkdownTOC depth=3 -->

- 1. 点和矢量的表示与支持
  - 1.1. 创建 Point 类
  - 1.2. 明确 Vector 类的接口
- 2. 绘图能力增强
  - 2.1. 添加图形类 `RegularPolygon`、`Star`、`Sweep`
  - 2.2. 提供 `Path.getPathSegment()` 方法
- 3. 坐标系统和 Matrix 升级
  - 3.1. 添加接口 `setTranslate()`、`setRotate()`、`setScale()`
  - 3.2. 删除 `Shape.setTransform()` 接口，改为 `Shape.setMatrix()` 接口
  - 3.3. `Shape.getTransform()` 添加参数 `refer`
- 4. Text 支持升级
  - 4.1. 提供垂直方向上的定位方式
  - 4.2. 添加超链接类 HyperLink
  - 4.3. 文本支持换行
  - 4.4. 升级阻力
- 5. 动画升级
  - 5.1. 开放动画帧接口：`kity.Timeline.requestFrame(frame)`
  - 5.2. 支持 Motion 动画。
- 6. 添加箭头的支持
  - 6.1. 添加 `Marker` 类支持箭头定义。
  - [6.2. `Path` 上添加方法 `setMarker(start](#,end , mid)
- 7. 图形学支持
  - 7.1. 提供常用的图形学算法，包括：
- 8. 性能度量和优化
- 附录1. 接口使用统计
  - 抛弃的图形变换 API

<!-- /MarkdownTOC -->


## 1. 点和矢量的表示与支持

### 1.1. 创建 Point 类

所有点参数都用 Point 类表示。其中为了数据交换方便，规定：

- `Point` 实例具有 `x` 和 `y` 属性，表示其直角坐标
- `Point` 类具有构造函数 `Point(x, y)`
- `Point` 类具有 `offset(dx, dy)` 方法可以返回偏移后的点
- `Point` 重载 `toString()` 方法，返回字符串 `"{x} {y}"`
- `Point` 重载 `valueOf()` 方法，返回数组 `[x, y]`
- `Point.fromPolar(r, a [, aUnit])` 静态方法可以使用极坐标系参数创建点，其中 a 表示角度，r 表示距离。aType 表示角度单位，可取 `"deg"`（默认）、`"rad"`

### 1.2. 明确 Vector 类的接口

- 从 `Point` 继承
- `Vector.fromPoints(p1, p2)`
- `.square()`
- `.length()`
- `.add(Vector q)`
- `.minus(Vector q)`
- `.dot(Vector q)`
- `.project(Vector q)`
- `.normalize(Number length)`
- `.multipy(Number scale)`
- `.rotate(Number a [, String aUnit])`
- `.vertical()`
- `.reverse()`

#### 1.3. 使用 Point 的地方注意支持

- 绘图方法中的 x, y 参数可以用点 p 替换，包括：
  * moveTo(p)
  * moveBy(p)
  * lineTo(p)
  * lineBy(p)
  * arcTo(rx, ry, xr, laf, sf, p)
  * arcBy(rx, ry, xr, laf, sf, p)
  * carcTo(r, p, laf, sf)
  * carcBy(r, p, laf, sf)
  * bezierTo(p1, p2, p)
  * bezierBy(p1, p2, p)
- Shape.setTranslate()
- ShapeEvent.getPosition() 的返回值
- Rect.setPosition() 和 Rect.getPosition()
- Circle.setCenter() 和 Circle.getCenter()
- 等待补充





## 2. 绘图能力增强

### 2.1. 添加图形类 `RegularPolygon`、`Star`、`Sweep`

类设计：待定

### 2.2. 提供 `Path.getPathSegment()` 方法



## 3. 坐标系统和 Matrix 升级

### 3.1. 添加接口 `setTranslate()`、`setRotate()`、`setScale()`

### 3.2. 删除 `Shape.setTransform()` 接口，改为 `Shape.setMatrix()` 接口

### 3.3. `Shape.getTransform()` 添加参数 `refer`

    > 说明：
    > `getTransform()` 的结果是所有变换的总和（matrix + scale + rotate + translate）
    > `refer` 可取值为 `"paper"` 或 `"top"`，获得图形相对于所在的 paper 的变换
    > `refer` 可取值为 `"screen"`，获得图形相对于 `window` 的变换（私有用法，不公开）
    > `ShapeEvent.getPosition()`、`Shape.getRenderBox()` 同步支持 `refer` 参数，不过 `getPosition()` 默认参照 `"paper"`


## 4. Text 支持升级

### 4.1. 提供垂直方向上的定位方式

```js
// 升级前：
// 不支持
// 
// 升级后：
text.setTextAnchor('center', 'middle');
// text-anchor-x: 支持 'left'（默认）、'center'、'right'
// text-anchor-y: 支持 'top'、'baseline（默认）'、'middle'、'bottom'
```

### 4.2. 添加超链接类 HyperLink

```js
// 升级前：不支持

// 升级后：
var link = new kity.HyperLink('http://www.baidu.com');
var rect = new kity.Path().rect(50, 50, 50, 200);
var text = new kity.Text('百度一下');
link.addShapes([rect, text]);
paper.addShape(link);
```

### 4.3. 文本支持换行

- 换行接口 `appendLine()`
- 文本内容自动转义 `setContent("this is line 1\nthis is line 2")` 自动转为两行

```js
// 升级前：
var text1 = new kity.Text('this is line1').setY(0);
var text2 = new kity.Text('this is line2').setY(20);
paper.addShapes([text1, text2]);

// 升级后：
var text = new kity.Text('this is line1\nthis is line2').setLineHeight(20);
paper.addShape(text);
```

#### 4.3.4. 文本路径偏移支持

```js
var text = new kity.Text('this is a path text').setPath(path);

// 升级后：
text.setTextAnchor('12%', 'middle'); // 设置了 path 后 text-anchor-x 支持百分数
```

### 4.4. 升级阻力

垂直定位方案需要调研。



## 5. 动画升级

### 5.1. 开放动画帧接口：`kity.Timeline.requestFrame(frame)`

回调会针对 fn 函数提供回调参数：
   - `frame.time` - 当前帧触发时的事件戳，精确到 ms
   - `frame.elapsed` - 从首帧开始到当前帧经过的时间，单位为 ms。
   - `param.dur` - 从上一帧到当前帧经过的时间，单位为 ms。
   - `param.rate` - 当前帧率，单位为 hz（帧/秒）
   - ``
   - `param.next()`

### 5.2. 支持 Motion 动画。




## 6. 添加箭头的支持

### 6.1. 添加 `Marker` 类支持箭头定义。

### 6.2. `Path` 上添加方法 `setMarker(start [,end [, mid]])` 来使用箭头。

`Marker` 类的方法：

- `setSize(width, height)` - 设置箭头的尺寸
- `setRef(x, y)` - 设置箭头的参照点
- `setRotate()` - 设置箭头的角度，默认为 'auto'，跟随 Path 的切线方向。

```js
// 升级前
// 不支持

// 升级后
var marker1 = new kity.Marker().addShape( circle );
var marker2 = new kity.Marker().addShape( square );
var marker3 = new kity.Marker().addShape( triangle );
line.setMarker(marker1, marker2, marker3);
```

## 7. 图形学支持

### 7.1. 提供常用的图形学算法，包括：

- `kity.gc.distance(p1, p2)`
  计算两点距离

- `kity.gc.getBox(p1, p2)`
  返回 p1 和 p2 两点所表示的矩形区域

- `kity.gc.mergeBox(b1, b2)`
  返回包围 b1 和 b2 的最小矩形区域

- `kity.gc.getBoxIntersect()`
  返回矩形区域 b1 和 b2 的重合矩形区域，如果区域不存在返回 null

- *`kity.gc.getClosurePoly(points)`
  返回包围指定点集的最小多边形

- *`kity.gc.getClosureBox()`
  返回包围指定点集的最小矩形

- `kity.gc.parsePathString( pathString )`
  解析 path 字符串为 pathSegment

- `kity.gc.getPathLength( path )`
  返回一个 path 的长度

- `kity.gc.getPointOfPath( path, offset )`
  返回一个 path 在 offset 长度处的位置。
  * 返回的 `Point` 对象具有额外的 `tan` 属性，`tan` 是一个矢量对象 `Vector`，其方向为返回的点在 Path 上的切线方向，长度为该点的曲率半径。

*: 暂时无使用需求，但是直觉觉得比较需要




## 8. 性能度量和优化

8.1. 当前问题

当前对于 Kity 的性能没有度量，无法比较。

8.2. 建议

设计具有代表性的 benchmark，并且和竞品进行性能对比。竞品包括：

- svg.js
- rapheal
- d3.js
- zRender

目前可以想到的 benchmark 包括：

1. 绘图性能
2. 图形变换性能（平移、缩放、旋转）
3. 动画性能（图形数、帧率）
4. 不同平台对比结果（浏览器、移动端）

8.3. 阻力

benchmark 的设计有一定难度。需要设计出能度量性能的方案之后才能制定性能优化方案。

## 附录1. 接口使用统计

### 抛弃的图形变换 API

| Project / API         | setTransform() |
| ----------------------|----------------|
| Kity (Demo & Example) |              2 |
| Kity Formula          |              3 |
| Kity Formula Editor   |              5 |
| Kity Charts           |              7 |
| Kity Minder           |             12 |
| Total                 |             29 |
