模块8: 插件系统与扩展
20+ 官方插件与自定义扩展开发
1. 插件架构概述
@antv/g 的渲染器通过插件组合构建能力。每个渲染器注册一组插件,插件通过 Hook 系统注入到渲染流水线的各个阶段。
核心接口在 packages/g-lite/src/AbstractRenderer.ts,插件实现 AbstractRendererPlugin 接口。
2. 插件接口
// AbstractRendererPlugin 基类
abstract class AbstractRendererPlugin {
name: string;
context: CanvasContext;
// 初始化:注册 RenderingPlugin 到渲染流水线
abstract init(runtime: GlobalRuntime): void;
// 销毁
abstract destroy(runtime: GlobalRuntime): void;
// 添加渲染插件
addRenderingPlugin(plugin: RenderingPlugin): void;
}
// RenderingPlugin - 渲染流水线钩子
interface RenderingPlugin {
apply(context: RenderingPluginContext, runtime: GlobalRuntime): void;
}
3. 插件注册与使用
import { Renderer } from '@antv/g-canvas';
import { Plugin as DragNDropPlugin } from '@antv/g-plugin-dragndrop';
const renderer = new Renderer();
// 注册插件
renderer.registerPlugin(new DragNDropPlugin());
// 也可以在创建时传入
const renderer2 = new Renderer({
plugins: [new DragNDropPlugin()],
});
4. 插件生态全景
4.1 交互类插件
| 插件 | 包名 | 功能 |
| 拖拽 | g-plugin-dragndrop | PointerEvents 实现的拖放交互 |
| 手势 | g-plugin-gesture | 双指缩放、旋转等手势识别 |
| 相机控制 | g-plugin-control | 3D 场景的轨道/飞行相机控制 |
| 标注 | g-plugin-annotation | 图形标注和批注系统 |
// 拖拽插件使用示例
import { Plugin as DragNDrop } from '@antv/g-plugin-dragndrop';
renderer.registerPlugin(new DragNDrop({
isDocumentDraggable: true,
isDocumentDroppable: true,
dragstartDistanceThreshold: 10,
dragstartTimeThreshold: 100,
}));
circle.addEventListener('dragstart', (e) => {});
circle.addEventListener('drag', (e) => {});
circle.addEventListener('dragend', (e) => {});
4.2 物理引擎插件
| 插件 | 引擎 | 特点 |
g-plugin-box2d | Box2D (WASM) | 经典 2D 物理引擎 |
g-plugin-matterjs | Matter.js | 轻量级 2D 物理 |
g-plugin-physx | NVIDIA PhysX | 高性能 3D 物理 |
// Matter.js 物理引擎示例
import { Plugin as MatterPlugin } from '@antv/g-plugin-matterjs';
renderer.registerPlugin(new MatterPlugin());
// 给图形添加物理属性
const ball = new Circle({
style: {
cx: 200, cy: 50, r: 20, fill: 'red',
rigid: 'dynamic', // 动态刚体
density: 0.5,
restitution: 0.8, // 弹性
},
});
4.3 布局引擎
// Yoga Flex 布局
import { Plugin as YogaPlugin } from '@antv/g-plugin-yoga';
renderer.registerPlugin(new YogaPlugin());
const container = new Rect({
style: {
width: 400, height: 300,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 10,
},
});
4.4 3D 扩展
// 3D 插件 - 几何体、材质、光照
import { Plugin as Plugin3D } from '@antv/g-plugin-3d';
import { Plugin as DeviceRenderer } from '@antv/g-plugin-device-renderer';
renderer.registerPlugin(new DeviceRenderer());
renderer.registerPlugin(new Plugin3D());
// 创建 3D 网格
const cube = new Mesh({
style: {
geometry: new CubeGeometry(device, { width: 100 }),
material: new MeshPhongMaterial(device, { shininess: 30 }),
},
});
4.5 渲染风格插件
| 插件 | 效果 |
g-plugin-rough-canvas-renderer | 手绘风格 (rough.js + Canvas) |
g-plugin-rough-svg-renderer | 手绘风格 (rough.js + SVG) |
g-plugin-zdog-canvas-renderer | 伪 3D 卡通风格 (Zdog) |
4.6 其他插件
| 插件 | 功能 |
g-plugin-css-select | CSS 选择器查询场景图节点 |
g-plugin-a11y | 无障碍:为图形生成 ARIA 描述 |
g-plugin-gpgpu | GPU 并行计算 (通用计算) |
5. 自定义插件开发
import { AbstractRendererPlugin } from '@antv/g-lite';
class MyPlugin extends AbstractRendererPlugin {
name = 'my-plugin';
init(runtime) {
// 注册渲染插件
this.addRenderingPlugin({
apply(context, runtime) {
const { renderingService } = context;
// 在各阶段注入逻辑
renderingService.hooks.beginFrame.tap(
'MyPlugin',
() => { /* 每帧开始时执行 */ }
);
renderingService.hooks.afterRender.tap(
'MyPlugin',
() => { /* 每帧渲染后执行 */ }
);
},
});
}
destroy(runtime) {
// 清理资源
}
}
// 使用
renderer.registerPlugin(new MyPlugin());
6. 插件开发最佳实践
- 单一职责 - 每个插件只做一件事
- Hook 注入 - 通过 Hook 系统而非修改核心代码
- 延迟初始化 - 在 init 中注册,不在构造函数中做重活
- 清理资源 - 在 destroy 中释放所有资源
- 配置化 - 通过构造函数参数接受配置