整合营销服务商

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

免费咨询热线:

用HTML5构建一个流程图绘制工具

我们的开发工程中经常会使用到各种图,所谓的图就是由节点和节点之间的连接所形成的系统,数学上专门有一个分支叫图论(Graph Theroy)。利用图我们可以做很多工具,比如思维导图,流程图,状态机,组织架构图,等等。今天我要做的是用开源的HTML5工具来快速构造一个做图的工具。

工具选择

工预善其事,必先利其器。第一件事是选择一件合适的工具,开源时代,程序员还是很幸福的,选择很多。

  • flowchart.js http://adrai.github.io/flowchart.js/ , 基于SVG创建Flow Chart
  • go.js http://www.gojs.net/latest/index.html go.js 提供一整套的JS工具 ,支持各种交互式图表的创建。有免费版和收费版
  • joint.js http://www.jointjs.com/ joint.js 是另一个创建图标库的工具,也提供免费版和商业版
  • jsPlumb http://www.jsplumb.org/ jsPlumb是一套开源的流程图创建工具 ,小巧精悍,使用简单
  • d3 http://d3js.org 在html5领域,d3可谓是最好的可视化基础库,提供方面的DOM操作,非常强大。

最终,我选择了jsPlumb,因为它完全开源,使用很简单,用D3的话可能会多花很多功夫。joint.js也不错。大家可以根据自己的需要选择。

构建静态应用

下面我们一步一步的来使用jsPlumb来创建我们的流程图工具。

第一步是等待DOM和jsPlumb初始化完毕,类似document.ready()和jquery.ready(), 要使用jsPlumb, 需要把代码放在这个函数里:

jsPlumb.ready(function() {
    // ... your code goes here ...
}


创建一个jsPlumb的实例,并初始化jsPlumb的配置参数:

//Initialize JsPlumb
var color = "#E8C870";
var instance = jsPlumb.getInstance({
    // notice the 'curviness' argument to this Bezier curve.  the curves on this page are far smoother
    // than the curves on the first demo, which use the default curviness value.      
    Connector : [ "Bezier", { curviness:50 } ],
    DragOptions : { cursor: "pointer", zIndex:2000 },
    PaintStyle : { strokeStyle:color, lineWidth:2 },
    EndpointStyle : { radius:5, fillStyle:color },
    HoverPaintStyle : {strokeStyle:"#7073EB" },
    EndpointHoverStyle : {fillStyle:"#7073EB" },
    Container:"container-id"
 });


这里给给出了一些配置包括,连接线(这里配置了一个贝塞尔曲线),线的风格,连接点得风格。Container需要配置一个对应的DIV容器的id。(这里也可以使用setContainer的方法)

下面我们要创建一个节点(node),每一个节点可以用一个DIV来实现。我这里提供了一个函数来创建节点。

function addNode(parentId, nodeId, nodeLable, position) {
  var panel = d3.select("#" + parentId);
  panel.append('div').style('width','120px').style('height','50px')
    .style('position','absolute')
    .style('top',position.y).style('left',position.x)
    .style('border','2px #9DFFCA solid').attr('align','center')
    .attr('id',nodeId).classed('node',true)
    .text(nodeLable);

  return jsPlumb.getSelector('#' + nodeId)[0];
}


这里做的事情就是创建了一个DIV元素,并放在对应的容器的制定位置上,注意为了支持拖拽的功能,必须使用position:absolute 。

我使用D3来操作DOM,大家可能会更习惯JQuery,这纯属个人喜好的问题。

最后返回创建节点的实例引用,这是的selector使用了jsPlumb.getSelector()方法,它和JQuery的selector是一样的,这样用的好处是你可以使用不同的DOM操作库,例如Vanilla

下面我使用一个函数来创建端点/锚点(anchor),锚点就是节点上的连接点,用于连接不同的节点。

function addPorts(instance, node, ports, type) {
  //Assume horizental layout
  var number_of_ports = ports.length;
  var i = 0;
  var height = $(node).height();  //Note, jquery does not include border for height
  var y_offset = 1 / ( number_of_ports + 1);
  var y = 0;

  for ( ; i < number_of_ports; i++ ) {
    var anchor = [0,0,0,0];
    var paintStyle = { radius:5, fillStyle:'#FF8891' };
    var isSource = false, isTarget = false;
    if ( type === 'output' ) {
      anchor[0] = 1;
      paintStyle.fillStyle = '#D4FFD6';
      isSource = true;
    } else {
      isTarget =true;
    }

    anchor[1] = y + y_offset;
    y = anchor[1];

    instance.addEndpoint(node, {
      uuid:node.getAttribute("id") + "-" + ports[i],
      paintStyle: paintStyle,
      anchor:anchor,
      maxConnections:-1,
      isSource:isSource,
      isTarget:isTarget
    });
  }
}


instance是jsPlumb的实例

node是我们用addNode方法创建的Node实例

ports,是一个string的数组,指定端点的个数和名字

type,可能是output或者input,指定端点的种类,一个节点的输出端口可以连接另一个节点的输入端口。

这里anchor是一个四维数组,0维和1维分别是锚点在节点x轴和y轴的偏移百分比。我这里希望把端口画在节点的左右两侧,并按照端口的数量均匀分布。

最后使用instance.addEndpoint来创建端点。注意这里只要指定isSource和isTarget就可以用drag&drop的方式来连接端点,非常方便。

下面一步我们提供一个函数来连接端点:

function connectPorts(instance, node1, port1, node2 , port2) {
  // declare some common values:
  var color = "gray";
  var arrowCommon = { foldback:0.8, fillStyle:color, width:5 },
  // use three-arg spec to create two different arrows with the common values:
  overlays = [
    [ "Arrow", { location:0.8 }, arrowCommon ],
    [ "Arrow", { location:0.2, direction:-1 }, arrowCommon ]
  ];

  var uuid_source = node1.getAttribute("id") + "-" + port1;
  var uuid_target = node2.getAttribute("id") + "-" + port2;

  instance.connect({uuids:[uuid_source, uuid_target]});
}


node1和node2是源节点和目标节点的引用,port1和port2是源端口和目标端口的名字。

使用instance.connect方法来创建连接。 overlays用来添加连接线的箭头效果或者其他风格,我这里没有使用,因为觉得都不是很好看。大家如果要用,只要把overlays加入到instance.connect的方法参数就可以了。

调用以上方法来创建节点,端点和连接线。

var node1 = addNode('container-id','node1', 'node1', {x:'80px',y:'20px'});
var node2 = addNode('container-id','node2', 'node2', {x:'280px',y:'20px'});

addPorts(instance, node1, ['out1','out2'],'output');
addPorts(instance, node2, ['in','in1','in2'],'input');

connectPorts(instance, node1, 'out2', node2, 'in');


这里我们创建了两个节点,第一个节点有两个输出端口,第二个节点有三个输入端口,然后把第一个节点的out2端口连接到第二个端点的in端口。效果如下:

最后我们给节点增加drag&drop的功能,这样我们就可以拖动这些节点来改变图的布局了。

instance.draggable($('.node'));


这里似乎依赖于JQuery-UI,我还不是很清楚。

交互式创建节点

我们已经初步具有了创建图的功能,可是节点的创建必须通过程序,我们希望用交互的方式来创建节点。

通常我们希望有一个tree view的控件,让后通过拖拽来创建对应类型的节点。这里我使用了这个开源的tree view,基于bootstrap https://github.com/jonmiles/bootstrap-treeview

我们先创建一个tree view:

function getTreeData() {
  var tree = [
    {
      text: "Nodes",
      nodes: [
        {
          text: "Node1",
        },
        {
          text: "Node2"
        }
      ]
    }
  ]; 

  return tree;
}
//Initialize Control Tree View
$('#control-panel').treeview({data: getTreeData()});


树上有两个节点:

然后我实现从树上拖拽对应的节点,到流程图上的逻辑。

//Handle drag and drop
$('.list-group-item').attr('draggable','true').on('dragstart', function(ev){
  //ev.dataTransfer.setData("text", ev.target.id);
  ev.originalEvent.dataTransfer.setData('text',ev.target.textContent);
  console.log('drag start');
});

$('#container-id').on('drop', function(ev){
  //avoid event conlict for jsPlumb
  if (ev.target.className.indexOf('_jsPlumb') >= 0 ) {
    return;
  }

  ev.preventDefault();
  var mx = '' + ev.originalEvent.offsetX + 'px';
  var my = '' + ev.originalEvent.offsetY + 'px';

  console.log('on drop : ' + ev.originalEvent.dataTransfer.getData('text'));
  var uid = new Date().getTime();
  var node = addNode('flow-panel','node' + uid, 'node', {x:mx,y:my});
  addPorts(instance, node, ['out'],'output');
  addPorts(instance, node, ['in1','in2'],'input');
  instance.draggable($(node));
}).on('dragover', function(ev){
  ev.preventDefault();
  console.log('on drag over');
});


这里要注意的是要避免和jsPlumb拖拽端点的逻辑冲突,当检测到target是jsPlumb对象是需要直接从drop方法中退出以执行对应的jsPlumb的drop逻辑。

好了,一个绘制流程图的软件工具初步完工。

我把代码放在oschina的代码托管服务上了, 大家有兴趣可以去试试。

端很火,想自学前端的人也多。作为过来人,知道自学的辛苦。所以小编精心制作这份学习路线图,就是让想自学前端的小伙伴们有一份系统专业的学习资源和学习指导。

此学习路线图,历经两个月的时间,无论你是刚入门的小白,还是已经工作的前端开发者,都是必备的学习宝典!

一、前端学习路线图—流程篇

前端学习路线图

二、前端学习路线图—视频教程篇:

前端视频篇第一阶段-准备篇

本阶段前端课程共计5个知识点,小编为大家准备了5个学习教程

1、周期与目标

这一阶段的学习需要15天的时间

2、学完后目标

  1. 熟悉媒体查询和响应式设计,使得设计有适配不同的移动;

  2. 熟悉基础CSS的格式和CSS盒模式;

  3. 理解网页间是如何链接的、如何设计多列布局,可以处理表单字段和媒体元素;

  4. 理解如何创建和浏览一个基本的网页。

3、知识点:

1)开发工具的安装配置的介绍

sublime、webstorm、Visual Studio Code

2)HTML

理解如何浏览和创建网页、基本的语法规范、常用标签及属性、网页之间的链接与跳转、标签节点层级节点

3)CSS

基本语法和三种书写位置、选择器和格式化排版、盒模型的高级用法、常用布局模型

4)JavaScript入门

基础语法和变量、数据类型和数据类型转换、条件判断、循环语句、函数、数组等内置对象

5)京东首页实战

CSS代码抽象与复用、 浮动的盒子布局、padding 和 margin 使用、层级的使用、定位特性的各种使用场景

4、小编整理的视频教程如下

《前端与移动开发基础》

《CSS梅兰商城项目实战视频教程》

《JavaScript基础视频教程》

二、前端视频篇第二阶段-基础篇

本阶段前端课程共计4个知识点,共计1个免费配套视频涵盖

1、周期与目标:

学习周期:20天

2、学完后目标:

  • 能够基于jQuery实现炫酷效果和复杂的功能模块;

  • 能创造或添加自定义效果到网页上;

  • 能熟练添加标准的动画效果到网页上;

  • 熟练操作DOM模型。

3、知识点:

  • JavaScript基础

  • JS语言的基本构成、变量、数据类型、表达式、选择结构、循环结构、短路语句、函数基础

  • DOM + BOM

    DOM基本结构、节点对象的操作、事件特性及使用、常见的内置DOM对象、常见的BOM功能

  • 网页特效与进阶

    在网页特效中常用的编程接口、动画编程、事件对象和冒泡、缓动框架封装和旋转木马案例、正则表达式及应用

  • Jquery

  • 选择器、基本操作API、动画API、事件API、插件机制、原理分析、项目实战

4、小编整理的视频教程如下

《JavaScript 基础加强 》

三、前端视频篇第三阶段——核心篇

本阶段前端课程共计5个知识点,合计3个免费视频涵盖

1、周期与目标:

学习周期:20天

2、学完后目标:

  • 能够基于jQueryMobile/Zepto等框架进行移动端js功能开发;

  • 能够熟练使用html5/css3/ canvas进行移动端页面和功能效果开发,并且能够基于原生和框架进行响应式效果开发;

  • 能够基于jQuery、bootstrap等框架实现炫酷效果和复杂的功能模块;

  • 能够独立制作电商类,企业类网站,以及常见js动态效果。

3、知识点:

  • HTML5 + CSS3

    语义化结构、多媒体 、本地存储、其他常见API、CSS3 选择器、CSS3 边框、背景、阴影、CSS3 过渡和动画、CSS3 伸缩布局、Canvas

  • 服务端编程

    端的概念、Web 服务器的概念、服务器搭建、XML与JSON

  • PHP

    PHP基础语法 、PHP服务端编程基础

  • AJAX

    基本编程接口、异步数据交互、模板引擎的使用、跨域的实现方案、增量加载

  • 移动Web开发

  • 响应式布局、Bootstrap框架深度使用、Zepto.js库、预编译CSS

4、小编整理的视频教程如下

《最新H5+CSS3教程视频》 《最新AJAX教程》《传智前端就业班视频分享:移动web开发课程 》

四、前端视频篇第四阶段——进阶篇

本阶段前端课程共计4个知识点,合计2个免费视频涵盖

1、周期与目标:

学习周期:15天

2、学完后目标:

  • 熟练使用闭包、高级函数、立即执行函数(匿名函数)等;

  • 熟练使用元编程,解决Callback等;

  • 熟悉JavaScript基本语法。

3、知识点:

  • 面向对象在JS中的体现与实践

    面向对象理论、对象的基本概念、对象的属性和方法、通过字面量创建对象

  • 2)开发过程中常用的模式与思想

    开闭原则、MVC思想、高内聚低耦合、工厂模式

  • 3)JavaScript高级特性

    通过构造函数创建对象、原型对象、继承的多种实现方式、原型链、函数的本质以及 Function 构造函数、作用域链、闭包、沙箱模式

  • 4)封装一个自己框架

    选择器框架、CSS操作封装、属性操作封装、其他DOM操作的封装、事件框架的封装

4、小编整理的视频教程如下:

《JavaScript-高级面向对象视频教程》《JavaScript高级框架设计》

想获得教程,都可以私信小编哦!

anvas技术的诞生可谓是让绘图技术如虎添翼,本文将推荐一系列Canvas图形绘制、流程图、组织图、甘特图、全景图、3D库、VR/AR、图像编辑等方面的库,希望助你在Canvas绘图时寻得一把趁手的利器。

同时,愣锤将Canvas的相关资源进行的收录整理分类,更多的资源请关注Github项目地址awesome-canvas。目前该库持续维护中,已收录大约200+的Canvas库,以及资源网址、插件、书籍、博客等资源。

图形处理库

图形绘制是Canvas中最基本的内容,但是Canvas本身提供的api比较基础,开发起来低效。而且也缺少完整的事件系统、区域监测、缓存等等。下面让我们来看几款高效的图形处理库吧。

Konva

简介:Konva是一个 HTML5 Canvas JavaScript 框架, 通过扩展 Canvas 的 2D Context 让桌面端和移动端Canvas支持交互性,使其支持高性能动画、过渡、节点嵌套、分层、过滤、缓存、事件处理等等。Konva官方地址(https://konvajs.org/docs/sandbox/index.html)

除上述之外,文档相对友好,但也仅仅是相对于同类库的文档友好那么一滴滴,社区有维护一个中文文档。

fabric.js

简介: Fabric.js是一个可以轻松处理 HTML5 Canvas元素的框架,使得Canvas元素支持交互式对象模型,同时也是一个SVG-to-CanvasCanvas-to-SVG的解析器, fabric.js官方地址(http://fabricjs.com/demos/)

fabricjs是和konva同类型但是比konva更老牌的一个的Canvas库,目前github上Star数2万+

更多示例如下图所示:

图像编辑

市面上图像编辑的软件有很多,像大家所熟知的PS、sketch、axure、激萌、剪映等等。那么如果我们想开发类似的软件,有没有可以使用的库或者参考的开源软件呢?

miniPaint

简介:miniPaint [官方网站在线演示](https://viliusle.github.io/miniPaint/) - 在线版的PS。PS这款软件大家都不陌生,web版本的如何呢?请看下图:

DarkroomJS

简介:DarkroomJS [官方网站在线演示](https://pqina.nl/pintura/?affiliate_id=854594675) - 基于Fabricjs的浏览器端可扩展的图像编辑工具

fabric-brush

简介:fabric-brush [官方网站在线演示] (https://tennisonchan.github.io/fabric-brush/)- 基于Fabric.js的Canvas笔刷工具

fabricjs-image-editor-origin

简介:fabricjs-image-editor-origin [官方网站在线演示] (https://fabricjs-image-editor-f62330.netlify.app/)- Fabricjs图像编辑器

react-sketch

简介:react-sketch [官方网站在线演示] (http://tbolis.github.io/showcase/react-sketch/)- 基于React、Fabricjs的素描应用

glitch-canvas

简介:glitch-canvas [官方网站在线演示](https://snorpey.github.io/jpg-glitch/) - 给画布元素添加故障效果

animockup

简介:animockup [官方网站在线演示] (https://animockup.com/)- 在浏览器中创建动画模型,并导出为视频或动画GIF

物理引擎

物理引擎使用质量、速度、摩擦力和空气阻力等变量,模拟了一个近似真实的物理系统,为刚性物体赋予真实的物理效果,比如重力、旋转和碰撞等效果,让物体的行为表现的更加趋向真实。例如,守望先锋的英雄在跳起时,系统所设置的重力参数就决定了他能跳多高,下落时的速度有多快,子弹的飞行轨迹等等。

matter.js

简介: matter.js是一个用于 Web 的 JavaScript 2D 物理引擎库 matter.js官方地址(https://brm.io/matter-js/demo/#wreckingBall)

matter.js相较于老牌的 Box2D 引擎库更为轻量级(压缩版仅有 87 KB),并且在性能和功能方面也不逊色。

流程图/组织图/图编辑等

工业软件开发,一直是软件领域复杂而又重要的一环。其对技术人的要求要是更高的,下面看看有哪些可以辅助我们快速开发的库或者参考的场景吧。

gojs

简介: gojs是一款可以非常方便的开发交互式流程图、组织结构图、设计工具、规划工具、可视化语言的JavaScript图表库。 gojs.js官方地址(https://gojs.net/latest/)

  • GoJS用自定义模板和布局组件简化了节点、链接和分组。
  • 给用户交互提供了许多先进的功能,如拖拽、复制、粘贴、文本编辑、工具提示、上下文菜单、自动布局、模板、数据绑定和模型、事务状态和撤销管理、调色板、概述、事件处理程序、命令和自定义操作的扩展工具系统。

文档中提供了大量的demo可供参考,基本对于常见的图编辑程序做到了全覆盖。

butterfly

简介:butterfly [官方网站在线演示] (https://butterfly-dag.gitee.io/butterfly-dag/demo/analysis)一个基于JS的数据驱动的节点式编排组件库,同时适用于React/Vue2组件。

  • 丰富的DEMO,开箱即用
  • 全方位管理画布,开发者只需要更专注定制化的需求
  • 利用DOM/REACT/VUE来定制元素;灵活性,可塑性,拓展性优秀
  • 提供了中文文档,这点对英文不好的小伙伴很Nice

wireflow

简介:wireflow [官方在线演示](https://app.wireflow.co/) 用户流程图实时协作工具。

  • Wireflow 有超过 100 种自定义构建图形/卡可供使用,涵盖了大多数 Web 元素、交互和使用案例。
  • Wireflow 考虑到了协作。您可以邀请您的同事和他们一起实时设计下一个项目的用户流程。
  • 它具有内置的实时聊天功能,让您能够与您的队友进行交流,并且在您实时协作时仍然在同一个应用程序中。

flowy

简介:Flowy [官方在线演示](https://alyssax.com/x/flowy) - 用于创建流程图的最小javascript库。使创建具有流程图功能的 WebApp 成为一项非常简单的任务。通可以在几分钟内构建自动化软件、思维导图工具或简单的编程平台。

  • 响应式拖放、自动捕捉、自动滚动
  • 块重排、删除块、自动块居中
  • 条件捕捉、条件块移除、无依赖项

Workflow Designer

简介:Workflow Designer [官方在线示例] (https://guozhaolong.github.io/wfd/)- 基于G6和React的可视化流程编辑器。

web-pdm

简介:web-pdm [在线示例](https://erd.zyking.xyz/demo) - 用G6做的ER图工具,最终目标是想做成在线版的powerdesigner.

X-Flowchart-Vue

简介:X-Flowchart-Vue [官方在线演示] (http://oxoyo.co/X-Flowchart-Vue/)- 基于G6和Vue的可视化图形编辑器。

OrgChart

简介:OrgChart [官方在线演示] (https://dabeng.github.io/OrgChart/)- 简单直接的组织图插件

welabx-g6

简介:welabx-g6 [官方在线示例] (https://claudewowo.github.io/welabx-g6/dist/?_blank)- 基于G6和Vue的流程图编辑器。

全景图/AR/VR

5g的普及、虚拟现实/增强现实落地、元宇宙的火热......似乎让Canvas再度推上了技术的顶峰。下面让我来看看开发这些场景常见的Canvas库吧。

Pannellum

简介:Pannellum [官方在线演示] (https://pannellum.org/)- 轻量、免费、开源的web全景查看器。

Panolens.js

简介:Panolens.js [官方在线演示] (https://pchen66.github.io/Panolens/)- Panolens.js基于Three.JS,主要研究领域是全景、虚拟现实和潜在的增强现实。

JS-Cloudimage-360-View

简介:JS-Cloudimage-360-View [官方在线演示] (https://scaleflex.github.io/js-cloudimage-360-view/)一个简单的、交互式的资源,可以用来提供您的产品的虚拟游览。

A-Frame

简介:A-Frame [官方在线演示](https://aframe.io/) A-Frame 除了帮助您构建 360 度媒体播放器外,它还提供了许多附加功能。其他功能可帮助您增强网站的虚拟现实体验。

3D库

three.js

简介:three.js [官方在线演示](https://threejs.org/examples/) - 创建易于使用、轻量级、跨浏览器的通用3d js库。three.js就不多介绍了,大家想必都很熟悉。

zdog

简介:zdog [官方在线演示](https://zzz.dog/) - 基于canvas和SVG设计师友好的伪3D引擎

seen.js

简介:seen [官方在线演示] (http://seenjs.io/)- 使用SVG或Canvas渲染3D场景。

Oimo.js

简介:Oimo.js [官方在线演示](http://lo-th.github.io/Oimo.js/index.html#basic) - 轻量级的JS 3D物理引擎。

phoria.js

简介:phoria.js [官方在线演示](http://www.kevs3d.co.uk/dev/phoria/index.html) - 用于在 HTML5 画布 2D 渲染器上进行简单 3D 图形和可视化的 JavaScript 库。它不使用 WebGL。适用于所有 HTML5 浏览器,包括桌面、iOS 和 Android。

原文来自:https://juejin.cn/post/7038267477121302542