整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

WebCAD快速入门(在线CAD如何快速搭建和入门)网页浏览和编辑dwg

提示:目前提供两种在网页中浏览编辑CAD图纸方案,详细说明见:https://help.mxdraw.com/?pid=46

提示:MxDraw云图API教程:https://demo.mxdraw3d.com:3562/mxdrawcloud/index.html

提示:MxDraw云图github:https://github.com/mxcad

全新在线CAD平台,基于JavaScript、WebGL、C++、Node.js、Three.js技术,前台使用html5方式,在线处理二维、三维CAD图纸。可用于图纸管理、交流、批注、信息提取、三维展示等场景,支持dwg,dxf,dwf等文件格式,后台使用高效C++程序开发,异步多线程、多进程架构。平台前后台都提供js语言开发接口,开发人员就只需要会JS语言,就可以快速搭建自己的在线CAD绘图平台。该系统可以在Windows、Linux、Android、iOS等系统上使用,真正一份代码,全平台支持。

1)在线演示网址1:

https://www.mxdraw3d.com/sample/vuebrowse/


2)CAD与GIS结合演示网址,请使用chrome,或edge浏览器:

https://www.mxdraw3d.com/sample/mx-vuemap/?cmd=Mx_CADGISDemo


3)MxCAD云图:

https://www.mxdraw3d.com/


4)MxCAD云图图库:

https://www.mxdraw3d.com/drawinglibrary.html


5)MxDraw npm 包在线帮助:

https://mxcadx.gitee.io/mxdraw_docs/start/abstract.html#%E6%A6%82%E8%BF%B0


6)MxCAD npm 包在线帮助:

https://mxcadx.gitee.io/mxcad_docs/zh/


MxDraw与MxCAD区别:

MxDraw包主要用来浏览CAD图纸,如果不需要编辑CAD图纸使用MxDraw包

MxCAD包主是在MxDraw的基础上,增加了编辑功能,它相对于MxDraw更加复杂,如果需要在线编辑CAD图纸,就需要使用MxCAD包。

主要功能

支持AutoCAD R14 到AutoCAD 2021的所有dwg图纸格式,未来也将支持新出现的AutoCAD文件格式。

三维支持:创建锥、柱、环等基本几何体, 对几何体进行布尔操作(相加、相减、相交运算)、倒角、斜切、镂空、偏移、扫视,、几何空间关系计算(法线、点积、叉积、投影、拟合等)、几何体分析(质心、体积、曲率等)、空间变换(平移、缩放、旋转)等功能。

二维支持:CAD图纸信息搜索提取、测距离、算面积、批注、捕捉、正交、曲线离散、偏移、打断、阵列、扩展数据读写、扩展记录读写、构造选择集、动画、自定义实体、组、超连接、Undo、Redo、字典、图层、标注样式、线型样式、文字样式、视口、布局、用户坐标系、系统变量、图纸比较、动态提示等。

主要实体有:直线、圆弧、Polyline、样条线、圆、椭圆、椭圆弧、IMAGE、点、块引用、外部块参照、射线、云线、文本、多行文本、对齐标注、旋转标注、半径标注、直径标注、角度标注、布局、视口、图层、线型、文字样式、命名字典、标注、自定义实体、代理实体、反应器等。

主要编辑有:移动、夹点拉伸、偏移、删除、复制、粘贴、旋转、缩放、镜向、离散、图案填充、实心填充、打碎、计算曲线长、面积、最近点、交点、导角、文字变线条等。

几何运算:面积、夹角、向量、矩阵、旋转、缩放、最近点、最近距离、垂足、参数、镜向、平移、交点、打断、延伸、最短路径、最长路径。


下载开发包

点击 http://www.mxdraw.com/download.html下载开发包,界面如下图所示:

下载后的文件是安装程序,双击按照提示安装开发包,默认安装位置在: C:\Users\MxDraw\Documents\MxKd\MxDrawCloudServer

注意:开发包的内容很多,安装需要很长时间,请耐心等待!

安装目录内容如下:



运行演示

双击桌面快捷方式:

启动开始程序,界面如下:

按照界面操作,从上到下,点击三个按钮,启动服务。

注意:在启动前,关闭360杀毒软件,它会误报和拦截我们服务器程序访问网络。

注意:一定要防火墙允许我们的服务程序访问网络。

设置防火墙,允许这两个程序能访问网格:Bin\Release\node.exe和SRC\TsWeb\nodejs\node.exe,如下图:

启动后的效果如下:

1. 后台网站服务程序,如果用户有自己网站服务,可以不需要启动该程序。

2. MxDrawNodeJS服务,后台保存文件 ,和上传文件 ,文件格式转换的服务

3. MxCAD文件上传保存服务,CAD图纸编辑后,保存到服务器的服务

4. 前台演示效果:


5. 选择文件后:

6. 打开DWG图纸:

7. Browse模式运行效果:

8. MxCAD运行效果:

9. MxGIS运行效果:


10. Mx3D运行效果:

如何在自己系统中浏览dwg文件

在线看CAD图纸的原理是:CAD图纸文件上传到服务后台后,调用我们的格式转换程序,把CAD图纸文件转换成我们的CAD浏览格式wgh文件,然后把该文件传给前台JS程序加载显示CAD图纸。

为了对大的CAD图纸异步加载,CAD文件会转换成多个wgh文件。

DWG文件格式转换有两个方法:

方法1:调用我们后面服务转换,详细参考:https://help.mxdraw.com/?pid=115

方法2:调用MxFileConvert.exe转换,软件安装目录下:C:\Users\MxDraw\Documents\MxKd\MxDrawCloudServer\Bin\Release\MxFileConvert.exe有一个MxFileConvert.exe程序,使用它对CAD图纸做格式转换。

调用命令:

MxFileConvert.exe {"srcpath":"E:/1.dwg"} 或  MxFileConvert.exe "E:/1.dwg"

或使用nodejs调用:

windows:  node.exe mxconvert.js e:/1.dwg 或 node.exe mxconvert.js convert file=e:/1.dwg
linux:  ./node mxconvert.js /tmp/1.dwg 或 ./node mxconvert.js convert file=/tmp/1.dwg

后台JAVA程序如何调用MxFileConvert.exe转换CAD文件格式,代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class MyTest {
    // 后面java程序,调用我们exe程序转换dwg文件格式.
public static String CallMxFileConvert(String sDwgFile){
        // 我们转所程序路径.
String command = "C:/Users/MxDrawDEV/Documents/MxKd/MxDrawCloudServer/Bin/Release/MxFileConvert.exe";
Runtime rn = Runtime.getRuntime();
Process process = null;
 
        // 转换参数。
String sJsonParam = "{\"srcpath\":\"" + sDwgFile + "\"}";
String [] sRetJson = new String[1];
 
try {
            // 启动一个进程序,调用转换程序。
process = rn.exec(new String[]{command,sJsonParam});
final InputStream ins = process.getInputStream();
final InputStream errs = process.getErrorStream();
//确保子进程与主进程之间inputStream不阻塞
new Thread() {
@Override
public void run() {
BufferedReader inb = null;
String line = null;
try {
inb = new BufferedReader(new InputStreamReader(ins,"gbk"));
while ((line = inb.readLine()) != null) {
sRetJson[0] = line;
//System.out.println("executeMxExe - InputStream : " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null != inb)
inb.close();
if(null != ins){
ins.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
//确保子进程与主进程之间ErrorStream不阻塞
new Thread() {
@Override
public void run() {
BufferedReader errb = null;
String line = null;
try {
errb = new BufferedReader(new InputStreamReader(errs,"gbk"));
while ((line = errb.readLine()) != null) {
System.out.println("executeMxExe - ErrorStream : " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=errb)
errb.close();
if(null != errs){
errs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
int retCode = process.waitFor();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally{
if(null !=process ){
OutputStream  out = process.getOutputStream();
if(null != out){
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
process.destroy();
}
}
 
        // 返回转换结果。
return sRetJson[0];
}
 
    public static void main(String[] args) {   
     String sDwg = "e:/1.dwg";
     String sRetJson = CallMxFileConvert(sDwg);
     System.out.println(sRetJson);
    }
};


后台JAVA程序调用代码:https://demo.mxdraw3d.com:3562/MxFileConvert.java.7z

Node.js后台调用代码如下:

          
    /* POST upload listing. */router.post('/', upload.single('file'), function (req, res, next) {   
     // 得到上传文件   
      var file = req.file;        
     // MxFileConvert.exe在服务器的路径    
      var pathConvertExt = '"' + __dirname + "/../../../Bin/Release/MxFileConvert.exe" + '"';   
     // 准备调用参数,json格式,srcpath是dwg在服务器上的路径.  
      var cmdparam = '{"srcpath":"' + file.path + '"}';   
      var cmd = pathConvertExt + " " + cmdparam;  
      const exec = child_process.exec;       
     //调用MxFileConvert.exe进程,进行文件格式转换.   
      exec(cmd, (err, stdout, stderr) => {       
           if (err) {           
              res.json('{"code": 1, "message": "exec cmd failed"}');     
              }     
              else {     
                  // 转换成功,通过命令输出json格式字符串.       
                  res.json(stdout);   
              }  
      });
    });


比如: D:/test/test.dwg 转换后,生成文件: D:/test/buf/$test.dwg.xxx.wgh1,2.. 文件,如下图:

把这些生成的文件放到java的Web服务的目录下,必须前台网页可以直接下载这些文件,如下效果:http://localhost:3000/test/buf/$test.dwg.mxb1.wgh

到目前为止,后台的工作已经准备完成。


接下来如何在前台加载CAD图纸:

A.新建一个Vue工程

详细见:https://help.mxdraw.com/?pid=107

B.安装mxdraw npm插件

yarn add mxdraw 或 npm install mxdraw

C. 修改main.ts加载,初始化MxDraw插件

import { loadCoreCode } from "mxdraw"loadCoreCode()

如下图:

常生产生活中,我们会经常读到或使用各种类型的图表。圆环(圆弧)便是一种较常见的类型,用于直观展现某一数据指标占整体的比例。本文以 HTML Canvas 的实现为主(当然,SVG 党可以在了解原理后自行实现),逐层介绍圆环图表开发的一些主要思路和原理。

图1 所示是一些我们平时比较常见的一些圆环(圆弧)效果。虽然图形的主体构成都是圆弧,但不同效果在信息传达的功能上却略有差异。如:

  • 闭合的圆环可以表示流程 “进度” 的概念
  • 非闭合圆环一般用于状态量(标量)的展示,一般也称为 “仪表盘” 效果
  • 不同的色相可用于标识状态量的状态区间(如:低危-中危-高危 区间的标识可以使用三种颜色的构成的过渡效果进行表达)

为了更加方便、完善地解决我们在业务开发时的具体需要,可以对这些风格、样式进行一定分析、抽象,总结出一个通用组件需要具备的能力,如:

  • 颜色、渐变可配(支持传入单一色值或颜色序列)
  • 圆弧宽度可调(内、外半径大小可配置)
  • 圆弧夹角可调(开始角度、截止角度可配置)
  • 圆弧端点造型可选(可切换平角/半圆造型
  • 文案效果可调(字号、字体、颜色等)

下面,我们着手于实现这样一个功能全面、业务通用性较强的圆环组件。

1. 圆环的造型

绘制圆环造型的第一步,需要先绘制圆环图表构成要素,即一段一段的圆弧。而对于像下图中这样的两种倒角效果(黄色部分圆弧两端的样式),既可以是直角,也可以是半圆。

因此,我们需要实现一个通用的方法来绘制圆弧,提供两种倒角风格给用户。

1.1 前景圆弧的绘制

圆弧绘制的思路如上图所示,按先后顺序大致分为几个步骤:

(1)绘制圆弧起始端的半圆轮廓

(2)绘制圆弧的外边缘轮廓

(3)绘制圆弧终止端的半圆轮廓

(4)绘制圆弧的内边缘轮廓

(5)闭合轮廓并填充色彩

注:由于 canvas 绘制圆弧的方法默认是顺时针方向,因而我们的绘图步骤也是沿着顺时针方向

以下是一些姿势要领:

1.1.1 端点坐标的计算

在绘制端点半圆之前我们需要端点的位置坐标,以其实端为例,根据圆环的半径(内外径的均值,即圆弧中线的半径)和起始端点的角度如何计算圆上一点的坐标:

// 计算圆弧上某点的坐标
// originX, originY - 圆心的坐标
// radius - 圆环半径,等于圆环内、外径的平均值,也即圆弧中线的半径
// alpha - 弧度
function calcPosition(originX, originY, radius, alpha) {
  return [
    radius * Math.cos(alpha) + originX,
    radius * Math.sin(alpha) + originY,
  ];
}

1.1.2 端点半圆的起止角度

在 canvas 中绘制一个 arc,需要知道其起始角度和终止角度。由于 canvas 绘制默认方向为屏幕顺时针方向(屏幕 Z轴 的左手螺旋方向),从上面的示意图中可以看出:

起始端半圆弧度范围 - [radianStart - Math.PI, radianStart]

终止端半圆弧度范围 - [radianEnd, radianEnd + Math.PI]

1.1.3 绘制半圆

有了端点坐标和起止角度,便可以绘制端点的半圆:

// 以起始端的半圆倒角为例
myCanvas.context.arc(
  x,
  y,
  (radiusOutter - radiusInner) / 2,     // 小圆半径,等于圆环线宽的一半
  radianStart - Math.PI,
  radianStart
);

直角倒角风格的绘制与半圆倒角圆弧的绘制步骤基本相同,主要差别在于不用绘制圆弧两个端点的小半圆,改成绘制直线。背景圆弧的绘制也与前景圆弧方法一致。

2. Canvas 实现锥形渐变

上面的步骤可以绘制出圆弧的轮廓,要达到 图1 那样的视觉效果,我们需要给前面绘制出来的轮廓填充图像。

沿着圆周方向的渐变,因为其图像形似圆锥体的俯瞰效果,俗称锥形渐变:

众所周知,CSS 中有一个名为 conic-gradient 的属性直接支持锥形渐变,而 HTML Canvas 的原生 API 目前还没有类似的能力。那么,我们如何在 canvas 中绘制出这样的图像呢?

下面我们讲下大致的原理:

(1)对用户传入的颜色进行插值,得到一个颜色序列。

这里,我们直接使用 canvas 原生的 createLinearGradient 方法,在离屏 canvas 中绘制一个 1px 的线性渐变效果,图像宽度正好是我们要插值的数量,渐变插值的结果也就是 canvas 上对应像素位置的色值。

颜色插值(渐变取色)代码实现如下:

// 用于实现颜色插值的工具类
export default class ColorInterpolate {
  // 参数01: stops - 为要插值的颜色序列,数据格式形如:[[0, 'red'], [0.5, 'green'], [1.0, 'yellow']]
  // 参数02: segment - 插值段落数,即插值结果的颜色值的数量
  constructor(stops = [], segment = 100) {
    // 构建离屏 canvas
    const canvas = document.createElement('canvas');
    canvas.width = segment;
    canvas.height = 1;
    this.ctx = canvas.getContext('2d');

    // 绘制线性渐变
    const gradient = this.ctx.createLinearGradient(0, 0, segment, 0);
    for (let [offset, color] of stops) {
      gradient.addColorStop(offset, color);
    }

    this.ctx.fillStyle = gradient;
    this.ctx.fillRect(0, 0, segment, 1);
  }

  // 根据位置偏移量获取插值后的色值
  getColor(offset) {
    const imgData = this.ctx.getImageData(offset, 0, 1, 1);
    return `rgba(${imgData.data.slice(0, 3).join(',')}, ${imgData.data[3] / 255})`;
  }
}

(2)如下图所示,我们可以把渐变的图像看成是由足够多填充了单个色值的小 “扇面” 拼接而成。

按照这样的思路,我们只需要遍历上面色彩插值得到的各个颜色,然后逐个绘制小扇面,便可得到一个锥形渐变图像。

为此我们封装了一个名为 createConicalGradient 的方法,其使用习惯与 canvas 原生的 createLinearGradient 和 createRadialGradient 方法相似。具体代码见 我的 Github(觉得有用的童鞋可以 star 一下)。

3. 过渡动画

3.1 圆弧的过渡

在数值发生改变时,我们的图表需要一个能够跟随数据改变的过渡动画效果,对于 canvas 而言,便是清除旧图像然后绘制新一帧图像。这里有一些方法包装上的技巧:

// 注:伪代码,真实场景建议 OOP 方式包装为工具类

let _animTick = null;
let _animFrames = null;
let _frameData = null;
let _animDiff = null;

// 动画方法
function _animate(duration) {
  if (_animTick === null) {
    // 根据动画时长 duration 计算整个动画一共需要多少帧(以 60fps 计算)
    _animFrames = Math.round((duration / 1e3) * 60);

    // 相邻两帧动画的数据变化
    _animDiff = _calcAnimDiff(_animFrames);

    // 动画帧数标识
    _animTick = 0;
  }

  // 当前帧的数据值
  _frameData = _caclCurentData(_animDiff, _animTick);
  _renderFrame(_frameData);

  if (_animTick !== null && _animTick < _animFrames) {
    // 继续执行动画
    window.requestAnimationFrame(() => {
      _animate();
      _animTick += 1;
    });
  } else {
    // 动画结束
    _renderFrame(_frameData);
    _animTick = null;
  }
}

// 绘制当前帧
function _renderFrame(data) {
  // ...
}

// 计算动画相邻帧的数据差异
function _calcAnimDiff() {
  // ...
}

// 根据两帧数据差计算当前帧
function _caclCurentData() {
  // ...
}

3.2 两种动画模式

在过渡动画执行的过程中,需要考虑两种不同的模式:一种是渐变图像不变化,仅是圆弧的轮廓从旧状态变化到新状态;一种是渐变图像的夹角范围跟随轮廓的大小改变。

这两种模式其实都有一定意义:前者可以使用不同颜色代表数值的不同状态;后者仅仅是将渐变的颜色看成一种装饰效果。

4. 结果演示

比较关键的原理都介绍完了,最后展示一下我们封装的图表组件的效果(右侧 GUI 部分是我们自研的设计引擎的编辑效果):

5. 写在后面

本文是可视化图表开发的一个小案例,。篇幅比较短,还有很多细节没有展开讨论。感兴趣的童鞋欢迎交流、留言!

辑导语:在从事设计行业过程中,或许有很多关于图标的问题困扰着设计思路。图标往往包含很多设计因素,如何搭建一个完整的图标体系是非常值得考虑的问题,本文作者收集关于图标设计问题,并进行一一解答,值得阅读学习。

从事设计很多年,是否还有很多与图标相关的问题困扰着你。比如:我们怎么去评判一个图标的好坏?画一个图标很简单,但是绘制一组图标时不知道该如何平衡,或是公司让我搭建图标体系,不知道该准备什么?…

下面是我收集到与图标相关的问题,如果你也有相同的疑惑,那么接下来我会通过将拆解国内外的大厂的图标体系为你解答,内含超多案例拆解!!

1. 图标概述

在解答问题之前,我们先来看看。图标的起源和发展是怎样的,以及为什么需要在界面上增加图标,它真的重要吗?

2. 图标定义

图标是什么呢?

从广义上来看具有指代意义的图形符号都叫做图标,图标具有高度浓缩、快捷传达信息且便于记忆的特性。应用的范围也很广,软硬件/网页/社交场所/公共场合无所不在。比如:男女厕所的标识/各种交通标志(禁止停车/掉头)都是我们常见的标识。

从狭义上来看特指计算机中的标志符号,比如数据标示/命令选择/状态指示等,都是通过对现实世界中事物的概括和隐喻,来引导人们在计算机中进行操作。这样说或许比较抽象,举个