Skip to content

绘制 Component 的 box

花生PeA edited this page Feb 23, 2019 · 6 revisions

将程序跑起来后,我们发现绘制出来的时间线上边除了字什么都没有。很正常,还记得各个叶子 Component 中的 draw() 吗?那里我们什么都没做,仅仅调用了super.draw()

接下来我们实现下AxisBody中的draw()

现在,我们的/Axis/AxisBody.ts代码应该是这样的:

import * as Engine from '@foxzilla/short-night';

export default class AxisBody extends Engine.AxisBody {
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

AxisBody负责绘制时间轴的轴体部分,我们在draw()中加上几行代码,来让他显示出来,代码如下:

    draw() {
+       const ctx = this.canvas.getContext('2d')!;
+       const box = this.drawInfo.box;
+
+       ctx.beginPath();
+       ctx.fillStyle = '#000000';
+       ctx.fillRect(box.x, box.y, box.width, box.height);
+
        return super.draw();
    }

完成后,刷新页面,你应该会看见页面上多了条黑色的竖线。如下图:

Draw box of AxisBody

让我们来解释下发生了什么。

首先,this代表当前 Component 本身,其身上有几个非常常用的属性:

  • canvas:存放用于绘制的 Canvas 元素
  • container:HTML元素的容器,通常是一个 DIV。如果一个 Component 需要创建 DOM 节点来完成自身的绘制,应该将 DOM 节点放进container
  • drawInfo:存放了所有 Component 自身所依赖的绘制信息,比如颜色、宽度、绘制坐标等
  • ext:扩展管理器,一个用于管理扩展的对象

而上边代码中,this.drawInfo.box所有 Component 都有的一个重要属性。它代表了该 Component 所占用的一个方块区域。该值是一个对象,拥有4个属性:

  1. x:方块区域的 x 坐标,相当于CSS中的left
  2. y:方块区域的 y 坐标,相当于CSS中的top
  3. width:方块区域的宽度,相当于CSS中的width
  4. height:方块区域的高度,相当于CSS中的height

所以,上边draw()的代码则清晰简单了很多,一言蔽之 —— 把组件所占的方块区域画在 Canvas 上。


接下来我们一一实现其他 Component 的draw()方法。

不同的 Component 内的drawInfo各不相同,但是所有的 Component 都一定有drawInfo.box。所以,我们不妨先把所有 Component 的drawInfo.box都画出来。

但在画之前,我们要明确一个概念:

只有6个叶子 Component 才负责绘制,其他的3个逻辑 Component (/Timeline.ts/Axis/index.ts/Event/index.ts)只是负责管理其叶子节点

所以,接下来我们绘制6个叶子节点,绘制不同的 Component 我们用不同的颜色以区分。

文件/Axis/AxisBody.ts

class AxisBody extends Engine.AxisBody {
     theme = 'polar-day';
 
     draw() {
+        const ctx = this.canvas.getContext('2d')!;
+        const box = this.drawInfo.box;
+
+        ctx.beginPath();
+        ctx.fillStyle = '#000000';
+        ctx.fillRect(box.x, box.y, box.width, box.height);
+
         return super.draw();
     }
 }

文件/Axis/AxisMilestone.ts

export default class AxisMilestone extends Engine.AxisMilestone {
     theme = 'polar-day';
 
     draw() {
+        const ctx = this.canvas.getContext('2d')!;
+        const box = this.drawInfo.box;
+
+        ctx.beginPath();
+        ctx.fillStyle = '#aaaaaa';
+        ctx.fillRect(box.x, box.y, box.width, box.height);
+
         return super.draw();
     }
 }

文件/Axis/AxisScale.ts

export default class AxisScale extends Engine.AxisScale {
     theme = 'polar-day';
 
     draw() {
+        const ctx = this.canvas.getContext('2d')!;
+        const box = this.drawInfo.box;
+
+        ctx.beginPath();
+        ctx.fillStyle = '#ff6600';
+        ctx.fillRect(box.x, box.y, box.width, box.height);
+
         return super.draw();
     }
 }

文件/Event/EventBody.ts

export default class EventBody extends Engine.EventBody {
     theme = 'polar-day';
 
     draw() {
+        const ctx = this.canvas.getContext('2d')!;
+        const box = this.drawInfo.box;
+
+        ctx.beginPath();
+        ctx.fillStyle = '#eeeeee';
+        ctx.fillRect(box.x, box.y, box.width, box.height);
+
         return super.draw();
     }
 }

文件/Event/EventMark.ts

export default class EventMark extends Engine.EventMark {
     theme = 'polar-day';
 
     draw() {
+        const ctx = this.canvas.getContext('2d')!;
+        const box = this.drawInfo.box;
+
+        ctx.beginPath();
+        ctx.fillStyle = '#ff0000';
+        ctx.fillRect(box.x, box.y, box.width, box.height);
+
         return super.draw();
     }
 }

改好后,刷新下页面,你可以应该可以看到下图效果:

Draw all box of component