本周参加了一次内部的技术分享,主题是甘特图项目技术改造,将原来基于 DOM 的绘制改为基于 canvas 绘制,其采用 React 描述 canvas 的思想让人眼前一亮,大致架构分为了三层:
1. canvas 作为最底层支持
2. 基于 canvas api 封装形状、事件之类的绘图及交互 api
3. 封装 react 组件,管理各形状的绘制及事件监听
对于直接使用 react 组件的用户,几乎不需要感知 canvas 相关的 api,即可完成高性能的凸显绘制。
实现的本质是将 react 提供的自定义渲染接口桥接到了 canvas 绘制 api。
前段时间,在知乎上也看到了一个类似的应用,不过是将 react 写的 UI 渲染到了嵌入式液晶屏上:将 React 渲染到嵌入式液晶屏
。
得益于 React 的分层设计,react 描述与渲染器分离,我们可以实现 react-reconciler 定义的接口,完成自定义绘制,替换掉我们常用的 react-dom 即可。
说回到借助 react 绘制 canvas,今天在 GitHub 上发现了一个项目也做了类似的工作:react-konva,比如:
const App = () => {
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Text text="Some text on canvas" fontSize={15} />
<Rect
x={20}
y={50}
width={100}
height={100}
fill="red"
shadowBlur={10}
/>
<Circle x={200} y={100} radius={50} fill="green" />
<Line
x={20}
y={200}
points={[0, 0, 100, 0, 100, 100]}
tension={0.5}
closed
stroke="black"
fillLinearGradientStartPoint={{ x: -50, y: -50 }}
fillLinearGradientEndPoint={{ x: 50, y: 50 }}
fillLinearGradientColorStops={[0, 'red', 1, 'yellow']}
/>
</Layer>
</Stage>
);
};
声明式的图形绘制,更加直观。