插件示例
大约 3 分钟
插件示例
本章提供一个完整的插件开发示例。
完整插件示例
// my-drawing-tools-plugin.ts
import type {
Plugin,
PluginManifest,
PluginContext,
CommandOptions,
RibbonButtonConfig
} from 'vjcad';
import {
Engine,
Point2D,
CircleEnt,
LineEnt,
PointInputOptions,
RealInputOptions,
IntegerInputOptions,
InputStatusEnum,
CadEvents
} from 'vjcad';
// ===== 命令1: 绘制带中心线的圆 =====
class CenterLineCircleCommand {
async main(): Promise<void> {
// 获取圆心
const centerOpt = new PointInputOptions("指定圆心:");
const centerResult = await Engine.getPoint(centerOpt);
if (centerResult.status !== InputStatusEnum.OK) return;
const center = centerResult.value;
// 获取半径
const radiusOpt = new RealInputOptions("指定半径:");
radiusOpt.defaultValue = 50;
const radiusResult = await Engine.getReal(radiusOpt);
if (radiusResult.status !== InputStatusEnum.OK) return;
const radius = radiusResult.value;
// 开始撤销组
Engine.undoManager.start_undoMark();
try {
// 创建圆
const circle = new CircleEnt(center, radius);
circle.setDefaults();
// 创建中心线
const extend = radius * 0.2;
const hLine = new LineEnt(
new Point2D(center.x - radius - extend, center.y),
new Point2D(center.x + radius + extend, center.y)
);
const vLine = new LineEnt(
new Point2D(center.x, center.y - radius - extend),
new Point2D(center.x, center.y + radius + extend)
);
hLine.setDefaults();
vLine.setDefaults();
hLine.lineType = 'CENTER';
vLine.lineType = 'CENTER';
// 添加实体
Engine.addEntities([circle, hLine, vLine], { recordUndo: true });
Engine.pcanvas.regen();
} finally {
Engine.undoManager.end_undoMark();
}
}
}
// ===== 命令2: 批量修改颜色 =====
class BatchColorCommand {
async main(): Promise<void> {
// 选择实体
const selResult = await Engine.getSelections();
if (selResult.status !== InputStatusEnum.OK || selResult.value.length === 0) {
return;
}
// 获取颜色
const colorOpt = new IntegerInputOptions("输入颜色索引 (1-255):");
colorOpt.defaultValue = 1;
const colorResult = await Engine.getInteger(colorOpt);
if (colorResult.status !== InputStatusEnum.OK) return;
// 修改颜色
Engine.setEntityColor(selResult.value, colorResult.value);
Engine.pcanvas.regen();
}
}
// ===== 插件定义 =====
const manifest: PluginManifest = {
id: 'drawing-tools',
name: '绘图工具集',
version: '1.0.0',
author: 'WebCAD Team',
description: '提供额外的绘图工具命令',
keywords: ['绘图', '工具', '圆']
};
const plugin: Plugin = {
manifest,
async onLoad(context: PluginContext): Promise<void> {
console.log('[绘图工具] 插件加载中...');
},
async onActivate(context: PluginContext): Promise<void> {
// 注册命令
context.registerCommand('CLCIRCLE', '带中心线的圆', CenterLineCircleCommand);
context.registerCommand('BATCHCOLOR', '批量修改颜色', BatchColorCommand);
// 注册图标
context.registerIcon('CLCIRCLE', `<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="2"/>
<line x1="4" y1="12" x2="20" y2="12" stroke="currentColor" stroke-dasharray="2,2"/>
<line x1="12" y1="4" x2="12" y2="20" stroke="currentColor" stroke-dasharray="2,2"/>
</svg>`);
// 添加到Ribbon
const buttons: RibbonButtonConfig[] = [
{ cmd: 'CLCIRCLE', label: '中心圆', tooltip: '绘制带中心线的圆' },
{ cmd: 'BATCHCOLOR', label: '批量颜色', tooltip: '批量修改实体颜色' }
];
context.addRibbonGroup('home', {
id: 'drawing-tools',
label: '绘图工具',
primaryButtons: buttons
});
// 监听事件
context.on(CadEvents.EntityAdded, (args) => {
console.log(`[绘图工具] 新实体: ${args.entity.type}`);
});
console.log('[绘图工具] 插件已激活');
},
async onDeactivate(context: PluginContext): Promise<void> {
context.unregisterCommand('CLCIRCLE');
context.unregisterCommand('BATCHCOLOR');
context.removeRibbonGroup('home', 'drawing-tools');
console.log('[绘图工具] 插件已停用');
},
async onUnload(context: PluginContext): Promise<void> {
console.log('[绘图工具] 插件已卸载');
}
};
export default plugin;插件加载方式
import { PluginManager, PluginSourceType } from 'vjcad';
const pluginMgr = PluginManager.getInstance();
// 从URL加载
await pluginMgr.loadPlugin({
type: PluginSourceType.Url,
js: 'https://example.com/plugins/my-plugin.js',
css: 'https://example.com/plugins/my-plugin.css',
autoActivate: true
});
// 从代码内容加载
await pluginMgr.loadPlugin({
type: PluginSourceType.Content,
js: pluginJsCode,
autoActivate: true
});插件管理
const pluginMgr = PluginManager.getInstance();
// 获取已加载插件
const plugins = pluginMgr.getLoadedPlugins();
// 激活插件
await pluginMgr.activatePlugin('my-plugin');
// 停用插件
await pluginMgr.deactivatePlugin('my-plugin');
// 卸载插件
await pluginMgr.unloadPlugin('my-plugin');
// 获取插件状态
const state = pluginMgr.getPluginState('my-plugin');插件开发要点
资源清理
在 onDeactivate 中清理所有注册的资源:
async onDeactivate(context: PluginContext): Promise<void> {
// 注销命令
context.unregisterCommand('MYCMD');
// 移除UI元素
context.removeRibbonGroup('home', 'my-group');
// 事件会自动清理,但也可以手动清理
}错误处理
async onActivate(context: PluginContext): Promise<void> {
try {
// 初始化逻辑
} catch (error) {
console.error('插件激活失败:', error);
throw error; // 抛出错误会将插件状态设为Error
}
}依赖管理
const manifest: PluginManifest = {
id: 'my-plugin',
name: '我的插件',
version: '1.0.0',
dependencies: ['base-tools'], // 依赖的插件
minEngineVersion: '1.0.0' // 最低引擎版本
};