(html在线预览cad图纸插件)网页CAD绘制条形码、二维码的教程

简介: 本文介绍了如何在mxcad中绘制条形码和二维码。对于条形码,首先根据应用场景选择合适的编码标准(如CODE39、EAN13等),通过编码规则将数据转换为二进制,并利用`McDbHatch`绘制条和空的组合,同时支持自定义实体及属性管理。对于二维码,因其能存储更多信息且具备更强纠错能力,采用开源库QRCode.js进行编码处理,再通过`McDbHatch`绘制黑白矩阵,同样封装成自定义实体以便管理和扩展。文中还给出了完整的绘制流程与效果展示,包括创建二维码对象、设置参数、调用绘制方法以及最终的效果图。整个过程体现了灵活运用API与第三方库来实现复杂图形绘制的能力。

一、条形码绘制

1.原理
绘制条形码需要根据不同的应用场景选择适当的条形码标准,如常见的 codabar 、CODE30、CODE128等,每一种条形码标准都有它特定的数据编码规则,调用这些编码规则进行数据编码时会将数据字符按照所选编码规则转换成条和空的组合(一组二进制数据)。不同的条形码标准使用不同的编码规则来表示0到9的数字或26个英文字母。
其中,为了确保扫描的准确性,条形码中还包括一个校验字符。这个字符通过特定的算法计算得出,用于检验整个条形码的准确性。在生成目标条形码时需对目标内容进行校验,若目标内容符合条形码的编码要求则再进行下一步的绘制。

2.mxcad实现绘制条形码
根据上述条形码绘制原理可知,只要我们能够知道条形码的编码规则将条形码内容转换为一串二进制数据并根据二进制数据的具体值确定条形码条、空的组合,我们就可以在 mxcad 中通过[填充实体McDbHatch]绘制出条形码,为方便后续对条形码的管理和扩展,我们可以将其绘制为[自定义实体McDbCustomEntity]并为其添加自定义属性。

1)条形码编码规则编写,下面以 CODE39 为例:

class Barcode{  constructor(data, options){  this.data = data; this.text = options.text || data; this.options = options; } } class CODE39 extends Barcode {  constructor(data, options){  data = data.toUpperCase(); // Calculate mod43 checksum if enabled if(options.mod43){  data += getCharacter(mod43checksum(data)); } super(data, options); } encode(){  // First character is always a * var result = getEncoding("*"); // Take every character and add the binary representation to the result for(let i = 0; i < this.data.length; i++){  result += getEncoding(this.data[i]) + "0"; } // Last character is always a * result += getEncoding("*"); return {  data: result, text: this.text }; } valid(){  return this.data.search(/^[0-9A-Z\-\.\ \$\/\+\%]+$/) !== -1; } } // All characters. The position in the array is the (checksum) value var characters = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "-", ".", " ", "$", "/", "+", "%", "*" ]; // The decimal representation of the characters, is converted to the // corresponding binary with the getEncoding function var encodings = [ 20957, 29783, 23639, 30485, 20951, 29813, 23669, 20855, 29789, 23645, 29975, 23831, 30533, 22295, 30149, 24005, 21623, 29981, 23837, 22301, 30023, 23879, 30545, 22343, 30161, 24017, 21959, 30065, 23921, 22385, 29015, 18263, 29141, 17879, 29045, 18293, 17783, 29021, 18269, 17477, 17489, 17681, 20753, 35770 ]; // Get the binary representation of a character by converting the encodings // from decimal to binary function getEncoding(character){  return getBinary(characterValue(character)); } function getBinary(characterValue){  return encodings[characterValue].toString(2); } function getCharacter(characterValue){  return characters[characterValue]; } function characterValue(character){  return characters.indexOf(character); } function mod43checksum(data){  var checksum = 0; for(let i = 0; i < data.length; i++){  checksum += characterValue(data[i]); } checksum = checksum % 43; return checksum; } export { CODE39}; 

更多编码规则可参考开源条形码js库JsBarCode

2) 实现自定义实体

import {  McGeVector3d, McDbHatch, McGePoint3d, McGePoint3dArray, McDbCustomEntity, IMcDbDwgFiler, MxCADWorldDraw, McDbEntity, McDbText, McDb, MxCpp, McGeMatrix3d } from 'mxcad'; import Barcode from './';// 引入条形码类型 // 自定义条形码 class McDbTestBarCode extends McDbCustomEntity {  /** 条形码位置 */ private position: McGePoint3d = new McGePoint3d(); /** 字高 */ private textHeight: number = 120; /** 条形码信息文字 */ private text: string = ''; // 条形码高度 private codeHeight: number = 300; // 条形码宽度 private codeWidth: number = 10; // 条形码类型 private codeType: string = 'CODE39'; // 条形码内容设置 private codeContent: string = 'ABCDEFG'; // 是否显示条形码文字内容 private showText: boolean = false; constructor(imp?: any) {  super(imp); } public create(imp: any) {  return new McDbTestBarCode(imp) } /** 获取类名 */ public getTypeName(): string {  return "McDbTestBarCode"; } //设置或获取基点 public set barCodePos(val: McGePoint3d) {  this.position = val.clone(); } public get barCodePos(): McGePoint3d {  return this.position; } //设置或获取条形码文字 public set barCodeText(val: string) {  this.text = val; } public get barCodeText(): string {  return this.text; } //设置或获取条形码高度 public set barCodeHeight(val: number) {  this.codeHeight = val; } public get barCodeHeight(): number {  return this.codeHeight; } //设置或获取条形码类型 public set barCodeType(val: string) {  this.codeType = val; } public get barCodeType(): string {  return this.codeType; } //设置或获取条形码宽度 public set barCodeWidth(val: number) {  this.codeWidth = val; } public get barCodeWidth(): number {  return this.codeWidth; } // 设置或获取条形码文字高度 public set barCodeTextHeight(val: number) {  this.textHeight = val; } public get barCodeHeigth(): number {  return this.textHeight; } // 设置或获取是否显示条形码文字内容 public set barCodeShowText(val: boolean) {  this.showText = val; } public get barCodeShowText(): boolean {  return this.showText; } // 设置或获取条形码文字内容 public set barCodeContent(val: string) {  this.codeContent = val; } public get barCodeContent(): string {  return this.codeContent; } /** 读取数据 */ public dwgInFields(filter: IMcDbDwgFiler): boolean {  this.position = filter.readPoint("position").val; this.codeWidth = filter.readDouble("codeWidth").val; this.codeHeight = filter.readDouble("codeHeight").val; this.textHeight = filter.readDouble("textHeight").val; this.text = filter.readString("text").val; this.codeType = filter.readString("codeType").val; this.codeContent = filter.readString("codeContent").val; const isShowText = filter.readLong("showText").val; this.showText = isShowText ? true : false; return true; } /** 写入数据 */ public dwgOutFields(filter: IMcDbDwgFiler): boolean {  filter.writePoint("position", this.position); filter.writeDouble("codeWidth", this.codeWidth); filter.writeDouble("codeHeight", this.codeHeight); filter.writeString("text", this.text); filter.writeDouble("textHeight", this.textHeight); filter.writeString("codeType", this.codeType); filter.writeString("codeContent", this.codeContent); const isShowText = this.showText ? 1 : 0; filter.writeLong("showText", isShowText); return true; } /** 移动夹点 */ public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {  this.assertWrite(); if (iIndex === 0) {  this.position.x += dXOffset; this.position.y += dYOffset; this.position.z += dZOffset; } }; /** 获取夹点 */ public getGripPoints(): McGePoint3dArray {  let ret = new McGePoint3dArray(); ret.append(this.position); return ret; }; /** 动态绘制 */ public worldDraw(draw: MxCADWorldDraw): void {  const code = new Barcode[this.codeType](this.codeContent, { flat: true}); if (!code.valid()) return alert('条形码类型与内容不匹配!请重新设置!'); let encoded = code.encode(); const v = McGeVector3d.kYAxis.clone().mult(this.codeHeight); const _v = McGeVector3d.kXAxis.clone().mult(this.codeWidth); encoded.data.split('').forEach((val, index) => {  const solid = new McDbHatch(); const point1 = new McGePoint3d(this.position.x + index * this.codeWidth, this.position.y, this.position.z); const point2 = point1.clone().addvec(v); const point3 = point2.clone().addvec(_v); const point4 = point1.clone().addvec(_v); const points = new McGePoint3dArray([point1, point2, point3, point4]); solid.appendLoop(points); if (val == '1') {  draw.drawEntity(solid); } }) if (this.showText) {  const text = this.getCodeText(); draw.drawEntity(text); } }; // 设置条形码文字实体 private getCodeText(): McDbEntity {  if (!this.text) this.text = this.codeContent; const text = new McDbText(); text.textString = this.text; text.height = this.textHeight; const v = McGeVector3d.kYAxis.clone().negate().mult(this.textHeight * (4 / 3)); text.position = text.alignmentPoint = this.position.clone().addvec(v); text.horizontalMode = McDb.TextHorzMode.kTextLeft; return text } // 编辑变换 public transformBy(_mat: McGeMatrix3d): boolean {  this.position.transformBy(_mat); return true; } } 

3)调用条形码自定义实体 McDbTestBarCode 绘制条形码

async function Mx_drawBarCode() {  const mxcad = MxCpp.getCurrentMxCAD(); mxcad.newFile(); mxcad.setViewBackgroundColor(255, 255, 255); // CODE39 类型条形码 const barCode = new McDbTestBarCode(); barCode.barCodePos = new McGePoint3d(100, 100, 0); barCode.barCodeShowText = true; mxcad.drawEntity(barCode); // CODE128 类型条形码 const barCode2 = new McDbTestBarCode(); barCode2.barCodeContent = 'A little test!'; barCode2.barCodeType = 'CODE128'; barCode2.barCodePos = new McGePoint3d(-2000, 100, 0); barCode2.barCodeShowText = true; mxcad.drawEntity(barCode2); // EAN13 类型条形码 const barCode3 = new McDbTestBarCode(); barCode3.barCodeContent = '5901234123457'; barCode3.barCodeType = 'EAN13'; barCode3.barCodePos = new McGePoint3d(-2000, -800, 0); barCode3.barCodeShowText = true; mxcad.drawEntity(barCode3); // codabar 类型条形码 const barCode4 = new McDbTestBarCode(); barCode4.barCodeContent = 'C1234567890D'; barCode4.barCodeType = 'codabar'; barCode4.barCodePos = new McGePoint3d(100, -800, 0); barCode4.barCodeShowText = true; mxcad.drawEntity(barCode4); mxcad.zoomAll(); mxcad.zoomScale(4); } 

4) 绘制效果演示:
image-20250115161107910.png

二、绘制二维码

1.原理
二维码是一种矩阵式二维条码,它能在水平和垂直两个方向上存储信息。二维码中的原始数据可以是数字、字母、二进制数据或其他字符‌,根据原始数据的类型,选择合适的编码模式。例如,数字数据使用数字模式,字母和数字混合使用alphanumeric模式,其他类型的数据则使用字节模式‌。
原始数据经过编码后的数据将放入一个二维矩阵中。这个过程可能需要使用掩模技术,通过应用特定的掩模图案来优化二维码中的黑白点的分布,避免出现与定位标记相似的模式‌,其中, 需要在矩阵的特定区域添加格式化和版本信息,以及必要时添加校正标记‌。

2.mxcad实现绘制二维码
二维码的编码规则我们可以直接借助二维码开源js库QRCode.js ,更多详细内容看参考:https://github.com/davidshimjs/qrcodejs
结合QRcode.js ,我们可以在mxcad中通过[填充实体McDbHatch]绘制出二维矩阵中的黑白块。为方便后续对二维码的管理和扩展,我们可以将其绘制为[自定义实体McDbCustomEntity]并为其添加自定义属性。
1)QRcode.js扩写:

// 增加 QRCode类的 makeMxcadCode 方法 QRCode.prototype.makeMxcadCode = function (sText) {  this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); this._oQRCode.addData(sText); this._oQRCode.make(); return this._oDrawing.drawMxcadHatch(this._oQRCode); }; 

绘制mxcad填充代码:

// 绘制mxcad填充代码(扩写Drawing类) Drawing.prototype.drawMxcadHatch = function (oQRCode): McDbEntity[] {  const entityArr = []; var _htOption = this._htOption; var nCount = oQRCode.getModuleCount(); var nWidth = _htOption.width / nCount; var nHeight = _htOption.height / nCount; for (var row = 0; row < nCount; row++) {  for (var col = 0; col < nCount; col++) {  var bIsDark = oQRCode.isDark(row, col); var nLeft = col * nWidth; var nTop = row * nHeight; if (bIsDark) {  // 矩形填充 const pos = new McGePoint3d(nLeft, nTop, 0); const v_y = McGeVector3d.kYAxis.clone().negate().mult(nHeight); const v_x = McGeVector3d.kXAxis.clone().mult(nWidth); const pos1 = pos.clone().addvec(v_y); const pos2 = pos.clone().addvec(v_x); const pos3 = pos.clone().addvec(v_x).addvec(v_y); const solid = new McDbHatch(); const ptArr = new McGePoint3dArray([pos, pos1, pos3, pos2]); solid.appendLoop(ptArr); entityArr.push(solid); } } } return entityArr; }; 

2)实现自定义实体

import {  MxCpp, McDbCustomEntity, McGePoint3d, IMcDbDwgFiler, McGePoint3dArray, MxCADWorldDraw, McGeMatrix3d, McDbEntity } from "mxcad"; import {  QRCode } from './qrCode' // 自定义二维码实体 class McDbTestQrCode extends McDbCustomEntity {  /** 二维码的位置 */ private position: McGePoint3d = new McGePoint3d(); // 二维码高度 private codeHeight: number = 300; // 二维码宽度 private codeWidth: number = 10; // 二维码内容设置 private codeContent: string = 'https://demo.mxdraw3d.com:3000/mxcad/'; constructor(imp?: any) {  super(imp); } public create(imp: any) {  return new McDbTestQrCode(imp) } /** 获取类名 */ public getTypeName(): string {  return "McDbTestQrCode"; } //设置或获取基点 public set qrCodePos(val: McGePoint3d) {  this.position = val.clone(); } public get qrCodePos(): McGePoint3d {  return this.position; } //设置或获取码高度 public set qrCodeHeight(val: number) {  this.codeHeight = val; } public get qarCodeHeight(): number {  return this.codeHeight; } //设置或获取码宽度 public set qrCodeWidth(val: number) {  this.codeWidth = val; } public get qrCodeWidth(): number {  return this.codeWidth; } // 设置或获取二维码内容 public set qrCodeContent(val: string) {  this.codeContent = val; } public get qrCodeContent(): string {  return this.codeContent; } /** 读取数据 */ public dwgInFields(filter: IMcDbDwgFiler): boolean {  this.position = filter.readPoint("position").val; this.codeWidth = filter.readDouble("codeWidth").val; this.codeHeight = filter.readDouble("codeHeight").val; this.codeContent = filter.readString("codeContent").val; return true; } /** 写入数据 */ public dwgOutFields(filter: IMcDbDwgFiler): boolean {  filter.writePoint("position", this.position); filter.writeDouble("codeWidth", this.codeWidth); filter.writeDouble("codeHeight", this.codeHeight); filter.writeString("codeContent", this.codeContent); return true; } /** 移动夹点 */ public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {  this.assertWrite(); if (iIndex === 0) {  this.position.x += dXOffset; this.position.y += dYOffset; this.position.z += dZOffset; } }; /** 获取夹点 */ public getGripPoints(): McGePoint3dArray {  let ret = new McGePoint3dArray(); ret.append(this.position); return ret; }; /** 动态绘制 */ public worldDraw(draw: MxCADWorldDraw): void {  const qrcode = new QRCode('', {  width: this.codeWidth, height: this.codeHeight }); const objArr = qrcode.makeMxcadCode(this.codeContent); objArr.forEach((obj: McDbEntity) => {  const entity = obj.clone() as McDbEntity; entity.move(new McGePoint3d(0, 0, 0), this.position); draw.drawEntity(entity); }) }; // 编辑变换 public transformBy(_mat: McGeMatrix3d): boolean {  this.position.transformBy(_mat); return true; } } 

3)调用二维码自定义实体McDbTestQrCode绘制二维码:

//画二维码 async function Mx_drawQrCode() {  const mxcad = MxCpp.getCurrentMxCAD(); mxcad.newFile(); const qrcode = new McDbTestQrCode(); qrcode.qrCodePos = new McGePoint3d(1000, 1000, 0); qrcode.qrCodeContent = 'https://demo.mxdraw3d.com:3000/mxcad/'; qrcode.qrCodeWidth = 1500; qrcode.qrCodeHeight = 1500; mxcad.drawEntity(qrcode); mxcad.zoomAll(); }; 

4) 绘制效果演示:
image-20250115163400393.png

相关文章
|
8月前
|
移动开发 JavaScript 前端开发
HTML5最新经典俄罗斯方块游戏插件
HTML5最新经典俄罗斯方块游戏插件
|
8月前
|
移动开发 前端开发 JavaScript
HTML5实现好看的劳动节网页源码
HTML5实现好看的劳动节网页源码,劳动节网页,劳动节网页源码,内置十个页面,各种模板都有,可以根据这些页面扩展更多页面,网页由网站首页、劳动节介绍、劳动节由来、劳动节习俗、劳动节文化、劳动节活动、劳动节故事、劳动节民谣、联系我们、登录/注册等页面组成,兼容手机端,页面干净整洁,内容丰富,可以扩展自己想要的,注释完整,代码规范,各种风格都有,代码上手简单,代码独立,可以直接运行使用。也可直接预览效果。
264 4
|
8月前
|
移动开发 HTML5
HTML5实现好看的中秋节网页源码
HTML5实现好看的中秋节网页源码,中秋节网页,中秋节网页源码,节日网页大作业,作业源码,内置十个页面,各种模板都有,可以根据这些页面扩展更多页面,网页由网站首页、中秋节介绍、中秋节由来、中秋节习俗、中秋节文化、中秋节美食、中秋节故事、中秋节民谣、联系我们、登录/注册等页面组成,兼容手机端,页面干净整洁,内容丰富,可以扩展自己想要的,注释完整,代码规范,各种风格都有,代码上手简单,代码独立,可以直接运行使用。也可直接预览效果。
416 0
HTML5实现好看的中秋节网页源码
|
9月前
|
移动开发 前端开发 JavaScript
HTML5实现好看的端午节网页源码
HTML5实现好看的端午节网页源码,包含十个页面:网站首页、端午节介绍、由来、习俗、文化、美食、故事、民谣、联系我们及登录/注册。页面设计简洁美观,内容丰富,兼容手机端,代码规范且注释完整,易于扩展和修改。提供完整的源码下载和视频演示,方便学习和使用。
270 3
|
9月前
|
存储 移动开发 JavaScript
网页 HTML 自动播放下一首音乐
在 HTML5 中实现自动播放下一首音乐,通过管理音乐列表、操作音频元素和监听事件完成。创建包含多个音乐链接的列表,使用 `&lt;audio&gt;` 元素加载音乐,监听 `ended` 事件,在当前音乐结束时自动播放下一首。示例代码展示了如何使用 JavaScript 实现这一功能,确保无缝切换音乐。
|
11月前
HTML在线扫雷游戏网页源码
HTML在线扫雷游戏网页源码是一款基于HTML+CSS+JavaScript开发的在线扫雷小游戏单页源码,为用户提供了一个无需安装即可在浏览器中直接玩的扫雷游戏。该游戏的源码不仅包含了完整的游戏逻辑,还具备丰富的界面设计和用户交互功能,使得玩家能够轻松上手并享受扫雷带来的乐趣。
400 22
|
11月前
|
数据采集 前端开发 数据挖掘
利用 html_table 函数轻松获取网页中的表格数据
本文介绍了如何使用 R 语言中的 `html_table` 函数结合代理 IP 技术,轻松提取网页表格数据并规避反爬机制。通过设置代理和请求头,示例代码展示了如何从 58 同城采集租房信息并保存为 CSV 文件。该方法适用于需要频繁采集数据的场景,确保数据采集的高效和稳定性。
390 2
利用 html_table 函数轻松获取网页中的表格数据
|
数据采集 移动开发 前端开发
HTML代码的革命:语义化标签的魅力,让你的网页结构焕然一新!
【8月更文挑战第26天】本文探讨了Web前端开发中的语义化标签概念及其重要性。语义化标签通过使用具有明确含义的HTML标签来构建页面结构,提升了网页的可访问性及搜索引擎优化效果,并增强了代码的可读性和维护性。文章还讨论了实际开发中遇到的问题及未来发展趋势。
261 0
|
数据采集 移动开发 搜索推荐
HTML基础-HTML5新增语义标签:解锁网页结构新维度
【6月更文挑战第5天】本文介绍了HTML5的语义标签,旨在提升网页结构化和可访问性。核心语义标签包括`&lt;header&gt;`、`&lt;nav&gt;`、`&lt;main&gt;`、`&lt;article&gt;`、`&lt;section&gt;`、`&lt;aside&gt;`、`&lt;footer&gt;`、`&lt;figure&gt;`和`&lt;figcaption&gt;`。常见问题包括滥用标签作布局工具、忽略`&lt;main&gt;`、不恰当嵌套和忽视辅助功能。
316 3
|
移动开发 前端开发 开发者
【专栏:HTML进阶篇】网页结构与语义化标签进阶
【4月更文挑战第30天】提升网页结构清晰度和无障碍访问性,有利于SEO。这些标签为屏幕阅读器提供额外上下文,简化CSS样式设计,避免无意义的&lt;div&gt;和&lt;span&gt;。正确使用语义化标签是现代网页开发的关键,能创造更优质、易访问和优化的Web体验。
207 0
下一篇