模块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-dragndropPointerEvents 实现的拖放交互
手势g-plugin-gesture双指缩放、旋转等手势识别
相机控制g-plugin-control3D 场景的轨道/飞行相机控制
标注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-box2dBox2D (WASM)经典 2D 物理引擎
g-plugin-matterjsMatter.js轻量级 2D 物理
g-plugin-physxNVIDIA 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-selectCSS 选择器查询场景图节点
g-plugin-a11y无障碍:为图形生成 ARIA 描述
g-plugin-gpgpuGPU 并行计算 (通用计算)

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. 插件开发最佳实践