Skip to content

Commit

Permalink
feat: visual format doc
Browse files Browse the repository at this point in the history
  • Loading branch information
chaxus committed Nov 30, 2024
1 parent bb9cf16 commit dc9e109
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 160 deletions.
147 changes: 145 additions & 2 deletions packages/docs/cn/src/article/visual.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,152 @@ class Container extends Vertex {

## 四:基础图形的封装

在多数二维绘图业务场景中,复杂图形往往可以简化为基础图形的巧妙组合。核心的基础元素包括圆形、多边形以及贝塞尔曲线,它们是实现图形构建的基本单位。
在多数二维绘图业务场景中,复杂图形往往可以简化为基础图形的组合。核心的基础元素包括圆形、多边形以及贝塞尔曲线,它们是实现图形构建的基本单位。

此外,还有一些频繁使用的基础图形,如矩形、圆角矩形和椭圆,同样不可或缺。我们将这些统称为“基础图形库”,通过它们的灵活组合,能够轻松构建出满足各种业务需求的图形场景。
此外,还有一些常用的基础图形,如矩形、圆角矩形和椭圆。我们将这些统称为“基础图形库”,通过它们的灵活组合,能够轻松构建出满足各种需求的二维场景。

首先我们定一个`Graphics`类,继承自 `Container` 类,表示绘制各种图形的容器。

```ts
class Graphics extends Container {}
```

绘制的过程中,我们需要考虑是填充还是描边图形。因此,需要定义两个属性:
`lineStyle``fillStyle`,用来表示 line 的属性,和 fill 的属性。

line 的属性有:color,alpha,visible,width,[cap](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap),[join](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin),[miterLimit](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/miterLimit)

填充的属性有:color,alpha,visible

我们可以用两个类去描述这些数据,Fill 类:

```ts
class Fill {
public color = '#ffffff';
public alpha = 1.0;
public visible = false;

constructor() {
this.reset();
}

public clone(): Fill {
const obj = new Fill();
obj.color = this.color;
obj.alpha = this.alpha;
obj.visible = this.visible;
return obj;
}

public reset(): void {
this.color = '#ffffff';
this.alpha = 1;
this.visible = false;
}
}
```

Line 类既有 Fill 类的所有属性,还有些其他的属性,所以可以继承 Fill 类:

```ts
class Line extends Fill {
public width = 0;
public cap = LINE_CAP.BUTT;
public join = LINE_JOIN.MITER;
public miterLimit = 10;

public clone(): Line {
const obj = new Line();
obj.color = this.color;
obj.alpha = this.alpha;
obj.visible = this.visible;
obj.width = this.width;
obj.cap = this.cap;
obj.join = this.join;
obj.miterLimit = this.miterLimit;
return obj;
}

public reset(): void {
super.reset();
this.color = '#ffffff';
this.width = 0;
this.cap = LINE_CAP.BUTT;
this.join = LINE_JOIN.MITER;
this.miterLimit = 10;
}
}
```

因此,`Graphics`类的属性如下:

```ts
class Graphics extends Container {
private _lineStyle = new Line();
private _fillStyle = new Fill();
constructor() {
super();
this.type = GRAPHICS;
}
}
```

还需要增加一些画线的方法和填充的方法:

```ts
class Graphics extends Container {
private _lineStyle = new Line();
private _fillStyle = new Fill();
constructor() {
super();
this.type = GRAPHICS;
}
public lineStyle(width: number, color?: string, alpha?: number): Graphics;
public lineStyle(options: ILineStyleOptions): Graphics;
public lineStyle(options: ILineStyleOptions | number, color: string = '0x000000', alpha: number = 1): Graphics {
this.startPoly();
if (typeof options === 'object') {
Object.assign(this._lineStyle, options);
} else {
const opts: ILineStyleOptions = { width: options, color, alpha };
Object.assign(this._lineStyle, opts);
}
this._lineStyle.visible = true;
return this;
}
// 如果要填充图形,则需要先调用这个函数给画笔设置填充色
public beginFill(color = '#000000', alpha = 1): Graphics {
this._fillStyle.color = color;
this._fillStyle.alpha = alpha;
if (this._fillStyle.alpha > 0) {
this._fillStyle.visible = true;
}
return this;
}
/**
* 结束填充模式
*/
public endFill = (): Graphics => {
this.startPoly();
this._fillStyle.reset();
return this;
};
}
```

接下来是绘制各种基础图形了,先从最简单的圆形开始。Graphics 类事绘制各种图形的容器,因此所有的基础图形绘制方法都在 Graphics 类上。增加绘制圆形的方法:

```ts
/**
* 画圆
* @param x 圆心 X 坐标
* @param y 圆心 Y 坐标
* @param radius 半径
*/
public drawCircle = (x: number, y: number, radius: number): Graphics => {
return this.drawShape(new Circle(x, y, radius));
};
```



Expand Down
10 changes: 8 additions & 2 deletions packages/ranuts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
const app = new Application({
view: document.getElementById('hierarchy'),
});
console.log('app', app);
const blackGraphic = new Graphics();
blackGraphic.beginFill('black');
blackGraphic.beginFill('white');
blackGraphic.drawRect(0, 0, 300, 300);

const redGraphic = new Graphics();
Expand All @@ -39,13 +40,18 @@
container2.addChild(greenGraphic);

const yellowGraphic = new Graphics();
yellowGraphic.beginFill('yellow');
// yellowGraphic.beginFill('yellow');
yellowGraphic.lineStyle({ width: 30, color: 'yellow', cap: 'round', join: 'round' });
yellowGraphic.drawRect(0, 0, 250, 150);

app.stage.addChild(container2);
app.stage.addChild(yellowGraphic);

app.render();

setTimeout(() => {
yellowGraphic.position.set(200, 0);
app.render();
}, 1000);
</script>
</body>
Expand Down
25 changes: 15 additions & 10 deletions packages/ranuts/src/utils/visual/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,29 @@ export class Application {
private renderer: Renderer;
public stage = new Container();
public view: HTMLCanvasElement;
public requestAnimationId?: number;

constructor(options: IApplicationOptions) {
const { view } = options;
const { view = document.createElement('canvas') } = options || {};
this.view = view;
this.renderer = getRenderer(options);
// this.start();
this.render();
// this.render();
}

public render(): void {
public render = (): void => {
this.renderer.render(this.stage);
}

private start() {
};
public start = (): number => {
const func = () => {
this.render();
requestAnimationFrame(func);
return requestAnimationFrame(func);
};
func();
}
this.requestAnimationId = func();
return this.requestAnimationId;
};
public destroy = (): void => {
if (this.requestAnimationId !== undefined) {
cancelAnimationFrame(this.requestAnimationId);
}
};
}
4 changes: 4 additions & 0 deletions packages/ranuts/src/utils/visual/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ export const MAX_VERTEX_COUNT = 65536; // 支持的最大的顶点数量
export const BYTES_PER_VERTEX = 12; // 每个顶点占多少字节

export const CONTAINER = 'container';

export const GRAPHICS = 'graphics';

export const OBJECT = 'object';
Loading

0 comments on commit dc9e109

Please sign in to comment.