写点什么

(JS 实现编辑 DWG)AI 实现网页 CAD 多行文本开发

作者:WEB CAD SDK
  • 2025-04-28
    四川
  • 本文字数:6203 字

    阅读完需:约 20 分钟

(JS实现编辑DWG)AI实现网页CAD多行文本开发

前言

AI 学习 MxCAD 文档后,给大家提供了一个名为 MxCADMText 的自定义编辑器实体类,用于在 CAD 中渲染和管理富文本编辑器。基于该类,我们可以将富文本编辑器中的强大功能转移实现在我们的 MxCAD 项目中,在线 demo 中已经更新了多行文本编辑器功能:https://demo2.mxdraw3d.com:3000/mxcad/

 

在原本的富文本编辑器功能上,我们将文本与 CAD 功能相结合实现了多行文本的扩展,用户可以根据自己项目的需求将实体以文本内容的形式插入到我们的多行文本内,接下来我们将详细讲述如何在 MxCAD 项目的多行文本编辑功能中插入自定义文本实体,富文本编辑功能示例:


注册同心圆实体文本

下面我们将以在多行文本编辑器中插入一个同心圆实体文本作为示例,介绍基础的扩展步骤。

1.实现自定义文本类

 MxCADMText 类中注册的所有自定义文本实体都需要继承 MxCADBaseCustomText 这个自定义文本基类,否则多行文本实体内部将无法识别你的自定义文本。

     /**    * 同心圆自定义文本类    * 用于在MxCAD多行文本中插入同心圆    */   class MxCADConcentricCircles extends MxCADBaseCustomText {     // 自定义文本的类型唯一标识     type = "MxCADConcentricCircles";     /**      * 计算同心圆的尺寸      * @param entity MxCAD多行文本实体      * @param textNode 文本节点      * @returns 计算数据,包含宽度和高度      */     calculate(entity: MxCADMText, textNode: MarksStyleText): MxCADCustomTextCalculateData {       // 获取外圆半径       const outerRadius = this.getOuterRadius(entity, textNode);       // 计算同心圆占用的空间大小       const width = outerRadius * 2;       const height = outerRadius * 2;       return {         width,         height       };     }     /**      * 创建同心圆实体      * @param entity MxCAD多行文本实体      * @param textNode 文本节点      * @param calculateData 计算数据      * @param renderData 渲染数据      * @returns 创建的实体数组      */     create(       entity: MxCADMText,       textNode: MarksStyleText,       calculateData: MxCADCustomTextCalculateData,       renderData: CreateData     ): (McDbEntity | McDbCustomEntity)[] {       // 获取外圆半径       const outerRadius = this.getOuterRadius(entity, textNode);       // 计算中圆半径       const middleRadius = outerRadius * 0.7;       // 计算内圆半径       const innerRadius = outerRadius * 0.4;       // 创建同心圆实体       const circles: McDbEntity[] = [];       // 计算圆心位置       // renderData.position是左上角的位置       const leftTopPosition = renderData.position.clone();       // 将圆心位置从左上角偏移一个半径的距离,使同心圆左上角与renderData.position对齐       // 圆心坐标 = 左上角坐标 + 圆半径       const centerX = leftTopPosition.x + outerRadius;       const centerY = leftTopPosition.y - outerRadius;       // 创建最终圆心坐标       const centerPosition = new McGePoint3d(centerX, centerY, leftTopPosition.z);       // 创建外圆       const outerCircle = new McDbCircle();       outerCircle.radius = outerRadius;       outerCircle.center = centerPosition;       circles.push(outerCircle);       // 创建中圆       const middleCircle = new McDbCircle();       middleCircle.radius = middleRadius;       middleCircle.center = centerPosition;       circles.push(middleCircle);       // 创建内圆       const innerCircle = new McDbCircle();       innerCircle.radius = innerRadius;       innerCircle.center = centerPosition;       circles.push(innerCircle);       return circles;     }     /**      * 获取外圆半径      * @param entity MxCAD多行文本实体      * @param textNode 文本节点      * @returns 外圆半径      */     private getOuterRadius(entity: MxCADMText, textNode: MarksStyleText): number {       // 根据文本字体大小动态计算圆的半径       const fontSize = textNode?.fontSize || 1;       // 调整半径计算,使圆的大小合适       return fontSize * entity.textBaseHeight / 2.5;     }     constructor() {       super();     }   }
复制代码


注意:

   `create()`方法用于创建实际的图形实体。

   `calculate()`方法用于计算自定义文本在多行文本中占用的空间。

   `type`属性用于定义自定义文本的类型标识,该 type 将在 MxCADMText 类中作为唯一标识。

 2.注册自定义文本

在 MxCAD 项目内的 MxPluginContext 上下文对象中我们已经暴露出了`registerEditorCustomTextPlugin()`注册方法,将上述已经写好的类放入该方法中就可以在自定义文本中插入同心圆实体了。

/**    * 注册同心圆自定义文本插件    */   const insertConcentricCircles = MxPluginContext.registerEditorCustomTextPlugin(     new MxCADConcentricCircles(),      {       // 双击图形时的回调函数       onDbClick: (node) => {         console.log("双击了同心圆:", node);       },       // UI数据       uiData: {         // 图标         icon: "yuan",         // 文本         text: "同心圆",         // 提示文本         tip: "插入同心圆",         // 点击事件         onClick: () => {           // 插入同心圆           insertConcentricCircles({             // 这里可以传入自定义参数           });         }       }     }   );
复制代码

`insertConcentricCircles(props: any, isUpdate?: boolean)`方法中的 props 为外部传入的参数对象,可以用于设置实体的参数绘制,设置后通过`MxCADConcentricCircles `类内部`calculate()`或`create()`方法内的`textNode.props`中获取;isUpdate 参数是用于已经插入了实体对象并处于文本编辑状态时,单击或双击实体进行修改操作后通知多行文本修改节点内容。

// 插入同心圆并传入自定义参数     insertConcentricCircles({       // 例如,可以传入不同的半径比例       radiusRatio: {         outer: 1,         middle: 0.7,         inner: 0.4       }     });     /**        *更新       onDbClick: (node) => {       // ... 处理node数据,更新params       insertConcentricCircles(params, true);       }       */
复制代码


    // 在create方法中使用这些参数:     create(entity, textNode, calculateData, renderData) {       // 获取自定义参数       const radiusRatio = renderData.props?.radiusRatio || {         outer: 1,         middle: 0.7,         inner: 0.4       };       const outerRadius = this.getOuterRadius(entity, textNode);       const middleRadius = outerRadius * radiusRatio.middle;       const innerRadius = outerRadius * radiusRatio.inner;       // 其他代码...     }
复制代码


onDbClick:双击文本时的回调函数,该回调函数内有一个 node 回调参数,该参数内部包含了文本节点的数据,即`MxCADConcentricCircles `类内部的`textNode`。利用该函数可实现交互式自定义文本,例如在双击时显示一个对话框来修改参数。

MxPluginContext.registerEditorCustomTextPlugin(       new MxCADConcentricCircles(),        {         onDbClick: (node) => {           // 显示一个对话框来修改参数           showDialog(node, (newParams) => {             // 更新自定义文本             updateCustomText(node, newParams);           });         },         // 其他配置...       }     );
复制代码

uiData:设置插入实体在编辑器中的 ui 配置,其中 icon 值可以设置为 iconfont 字体图标。

3.在项目初始时执行注册事件
   function rxInitCircle() {      /**      ...params      设置初始参数      */     insertConcentricCircles(params)    }
复制代码


   // MxCAD创建成功,相当于mxcad init\_mxcad事件.   MxFun.on("mxcadApplicationCreatedMxCADObject", (param) => {       rxInitCircle()   }
复制代码
4.运行效果演示



扩展实践(注册粗糙度实体文本)

1.构造粗糙度自定义实体文本注册类
// 绘制最初始的文本实体   const getEntity = (entity: MxCADMText, textNode: MarksStyleText) => {     const roughness = new McDbTestRoughness();     roughness.setPos(new McGePoint3d(0, 0, 0));     roughness.rouDimHeight = (textNode?.fontSize ? textNode.fontSize : 1) * entity.textBaseHeight;     const form = textNode.props;     roughness.rougMarkType = form.selectSymbolNum;     roughness.textLeftStr = form.textLeftStr;     roughness.rougCornerType = form.rougCornerType === "无" ? "" : form.rougCornerType;     roughness.isRoungSameRequire = form.isRoungSameRequire;     roughness.isShowMostSymbols = form.isShowMostSymbols;     const dataArr = form.textUpStr.filter((item) => item != "");     roughness.textUpStr = JSON.parse(JSON.stringify(dataArr)).reverse();     roughness.textDownStr = form.textDownStr.filter((item) => item != "");     roughness.isAddRougLongLine = form.isAddLongLine;     return roughness   }   // 构建文本注册类   class MxCADTestRoughnessText extends MxCADBaseCustomText {     // type为后续多行文本插入的唯一标识     type = "MxCADTestRoughnessText"     calculate(entity: MxCADMText, textNode: MarksStyleText): MxCADCustomTextCalculateData {       const roughness = getEntity(entity, textNode);       const box = roughness.getBoundingBox();       const width = box.maxPt.x - box.minPt.x       const height = box.maxPt.y - box.minPt.y;       return {         width,         height       }     }     create(entity: MxCADMText, textNode: MarksStyleText, calculateData: MxCADCustomTextCalculateData, renderData: CreateData): (McDbEntity | McDbCustomEntity)[] {       const roughness = getEntity(entity, textNode);       const pos = roughness.getPos();       //设置粗糙度在文本中的位置       const { minPt, maxPt } = roughness.getBoundingBox();       const basePt = new McGePoint3d(minPt.x, maxPt.y);       const v = pos.sub(basePt)       const pt = renderData.position.clone().addvec(v)       roughness.setPos(pt);       if (entity.getMTextImp().entityType == 'mtext' && !entity.getMTextImp().isEditState) {         return [roughness]       } else {         const entityArr = roughness.getAllEntity();         return [...entityArr]       }     }     constructor() {       super()     }   }
复制代码
2.注册粗糙度文本

粗糙度弹框的具体实现可以具体参考https://blog.csdn.net/u013725001/article/details/146095121?spm=1001.2014.3001.5502 文章中介绍的在 MxCAD 项目中调用内部弹框的方法,或者参考在云图开发包中 MxCAD 项目内的`extools`目录下的实现源码。

// 注册粗糙度文本   function rxInitRoughnessText() {     // 使用插件上下文中的函数     const insertCustomText = MxPluginContext.registerEditorCustomTextPlugin(       new MxCADTestRoughnessText(),       {         // 双击文本时的回调函数         onDbClick: (node) => {           showRoughnessDialog(true, node as MarksStyleText)         },         uiData: {           icon: 'icon-a-1',           tip: '粗糙度',           onClick: () => {             // 插入自定义公式             showRoughnessDialog(false)           }         }       }     )     const showRoughnessDialog = (isUpdate: boolean = false, textNode?: MarksStyleText) => {       if (isUpdate) {         const roughness = new McDbTestRoughness();         const form = textNode.props;         roughness.rougMarkType = form.selectSymbolNum;         roughness.textLeftStr = form.textLeftStr;         roughness.rougCornerType = form.rougCornerType === "无" ? "" : form.rougCornerType;         roughness.isRoungSameRequire = form.isRoungSameRequire;         roughness.isShowMostSymbols = form.isShowMostSymbols;         roughnessHandle.value = roughness;            const dataArr = form.textUpStr.filter((item) => item != "");         roughness.textUpStr = JSON.parse(JSON.stringify(dataArr)).reverse();         roughness.textDownStr = form.textDownStr.filter((item) => item != "");         roughness.isAddRougLongLine = form.isAddLongLine;       }       dialog.showDialog(true, { title: t("表面粗糙度") }).then(async ({ data, isCanceled }) => {         // 需要等待cancel或者confirm调用才会触发         if (!isCanceled) {           insertCustomText(data.roughnessData, isUpdate)         }       });     }   }
复制代码
3.初始化粗糙度自定义文本
   // MxCAD创建成功,相当于mxcad init\_mxcad事件.   MxFun.on("mxcadApplicationCreatedMxCADObject", (param) => {       rxInitRoughnessText()   }
复制代码
4.实践效果演示

初始插入,如下图:

双击修改,如下图:

修改后最终以多行文本形式绘制在图纸中,如下图:


用户头像

WEB CAD SDK

关注

还未添加个人签名 2024-10-16 加入

还未添加个人简介

评论

发布
暂无评论
(JS实现编辑DWG)AI实现网页CAD多行文本开发_AI编程_WEB CAD SDK_InfoQ写作社区