es6 class 封装 canvas 绘图库需聚焦逻辑收拢、状态管理与接口清晰:分几何数据类、工具类、渲染引擎类三层;图表与交互组件各自治理生命周期与状态;严控像素比、路径重置、动画清理等细节。

用 ES6 Class 封装 Canvas 绘图库,核心是把重复绘图逻辑收拢、状态集中管理、接口语义清晰。不是简单套个 class 壳,而是让每个图形类型可独立创建、复用、销毁,同时避免 canvas 上下文污染和事件泄漏。
明确职责,拆分基础能力
不要在一个类里塞进所有功能。推荐按层级组织:
-
几何数据类:如
Point、Rect、Circle,带默认参数和基础方法(如contains(x, y)) -
工具辅助类:如
CanvasUtil,封装角度/弧度转换、颜色处理、坐标归一化等静态方法 -
绘图引擎类:如
CanvasRenderer,持有canvas和ctx,提供clear()、drawRect()、drawArc()等统一入口
封装图形绘制行为(非状态型)
对折线图、心率图、环形进度条这类有固定流程的图形,用独立 class 封装其绘制逻辑:
- 构造函数接收配置(宽高、颜色、数据源等),自动创建 canvas 或复用传入的 canvas 元素
- 提供
render(data)方法,内部完成坐标计算、路径生成、样式设置、绘制调用 - 支持
updateConfig()动态调整样式或范围,不重建实例 - 暴露
destroy()清理定时器、移除事件监听、置空引用(防内存泄漏)
管理交互与生命周期(状态型)
像画区域、拖拽点、多边形编辑这类需要用户操作的场景,类需维护完整状态:
- 用私有字段(如
#points、#isDrawing、#selectedIdx)隔离内部状态 - 绑定
mousedown/mousemove/mouseup到 canvas,并在dispose()中统一解绑 - 提供
startDraw()、cancel()、submit()等语义化方法,而非直接操作 DOM - 支持导出标准格式数据(如顶点数组),也支持从数据回填重绘(
load(points))
注意几个关键细节
ES6 封装不是语法糖,要解决真实问题:
- canvas 绘图必须手动管理像素比(
devicePixelRatio),缩放后宽高需同步设置canvas.width/height - 多次
beginPath()是必须的,否则路径会累积;stroke()和fill()要成对考虑 - 动画场景下,用
requestAnimationFrame替代setInterval,并在每次帧开始前clearRect - 若需多实例(如多个环形进度条),避免使用单例模式硬编码,改用工厂函数或导出 class 本身











