惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
月光博客
月光博客
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
人人都是产品经理
人人都是产品经理
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - Franky
The Cloudflare Blog
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
Last Week in AI
Last Week in AI

博客园 - 梦想CAD控件

网页CAD如何在web端实现AutoCAD的绘圆弧功能 网页CAD控件中对象捕捉的运用和二次开发方法(网页端编辑DWG) 网页端CAD的图形选择、编辑与夹点操作教程(CAD in WEB) 云原生CAD后台处理DWG(MxServiceCode) 网页CAD图纸保存与数据持久化(BS架构CAD插件) 网页CAD中命令行驱动与参数化绘图的使用教程 在线CAD视图控制与图层管理二开实战 Web CAD图形引擎实现DWG图纸网页批注和查看 开源网页实时协同设计平台-在线编辑CAD图纸 在线CAD SDK开发包图纸转换功能使用教程(在线CAD API) 统信麒麟鸿蒙系统软件集成CAD功能(国产系统CAD控件) 网页CAD开发包结构与功能说明(网页CAD实时协同编辑) 网页CAD结合AI实现自然语言设计CAD图纸 (JS实现预览)在线CAD中的“组”功能开发 (在线CAD)html在线预览cad图纸SDK集成方法 (JS编辑DWG文件)在线CAD二开实现图纸表格提取到excel 网页版CAD与gis结合实现在线地图和CAD编辑 (html在线预览cad图纸插件)在线CAD实现形位公差标注 (WEB CAD API )网页CAD插件如何开发焊接符号 (web cad sdk)在线CAD中配置属性的使用教程 (WEB CAD二次开发)在线CAD SDK调用内部弹框的方法 在线CAD插件通过上下文对象MxPluginContext修改UI界面的方法 国产操作系统中好用的CAD软件(统信,麒麟,信创环境安装CAD) (pdm集成CAD SDK)在线CAD绘制条形码、二维码的教程 在线CAD绘制门和窗(WEB CAD二次开发家装设计软件) 在线CAD绘制墙体(WEB端开发室内设计软件) (在线三维参数化建模)网页三维CAD中加载和保存STEP模型 (H5在线CAD SDK)在线CAD中线型表的使用方法 (web查看三维CAD图纸)在三维网页CAD中绘制一个窗户模型
(HTML VUE在线编辑DWG)网页CAD利用AI实现多行文本功能的开发
梦想CAD控件 · 2025-04-28 · via 博客园 - 梦想CAD控件

前言

在最新版本的 mxcad 插件中,我们提供了一个名为MxCADMText的自定义编辑器实体类,用于在CAD中渲染和管理富文本编辑器。基于该类,我们可以将富文本编辑器中的强大功能转移实现在我们的MxCAD项目中,目前我们的在线demo中已经更新了多行文本编辑器的相关功能,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. 实践效果演示

初始插入,如下图:

双击修改,如下图:

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