在绘制 dag 图时,通过节点和来箭头的连线来表示节点彼此之间的关系。而节点常常又带有状态,为了更好的表示节点之间的流程关系,loading 状态的节点,与后续节点之间,需要用 动画着的虚线 表示,表示正在处理中,处理完才会变成实线。原理同页面没加载出来之间,加个 loading 提示,能提供更好的交互体验

  • 那么如何用 gojs 实现这个效果呢?虚线,及虚线动画
  • 虚线及虚线动画的背后原理是什么?
  • 虚线为什么又叫蚂蚁线?
  • 纯 css 可以实现吗?

一、gojs 实现

gojs 的基础使用,可参考之前写的文章数据可视化 gojs 简单使用介绍

举例:国庆快到了,出游,从上海到北京,假设当前正在途径安徽到山东的路上。用 gojs 绘制出来如下:

1. 绘图

  1. <!-- 容器 -->
  2. <div id="myDiagramDiv" style="height:600px;width:100%;border:1px solid black"></div>
  1. <!-- 引入gojs -->
  2. <script src="https://unpkg.com/gojs/release/go.js"></script>
  1. // 生成器
  2. const $ = go.GraphObject.make;
  3. // 定义容器,myDiagramDiv 为容器 id
  4. const diagram = $(go.Diagram, 'myDiagramDiv');
  5. // 节点模板,描述了如何构造每个节点
  6. diagram.nodeTemplate = $(go.Node, "Auto", // 框自动适应文本
  7. $(go.Shape, "RoundedRectangle", new go.Binding("fill", "color")),
  8. $(go.TextBlock, {margin: 5}, new go.Binding("text", "name"))
  9. );
  10. // 定义model, 描述节点信息和连线信息
  11. diagram.model = new go.GraphLinksModel(
  12. [ // 节点
  13. { key: 'shanghai', name: "出发地 上海", color: "lightblue" },
  14. { key: 'jiangsu', name: "途径地 江苏", color: "pink" },
  15. { key: 'anhui', name: "途径地 安徽", color: "pink" },
  16. { key: 'shandong', name: "途径地 山东", color: "orange"},
  17. { key: 'hebei', name: "途径地 河北", color: "orange" },
  18. { key: 'tianjin', name: "途径地 天津", color: "orange" },
  19. { key: 'beijing', name: "目的地 北京", color: "lightgreen" }
  20. ],
  21. [ // 连线
  22. { from: "shanghai", to: "jiangsu" },
  23. { from: "jiangsu", to: "anhui" },
  24. { from: "anhui", to: "shandong" },
  25. { from: "shandong", to: "hebei" },
  26. { from: "hebei", to: "tianjin" },
  27. { from: "tianjin", to: "beijing" }
  28. ]
  29. );

至此,一个简单的出游途径地关系图就绘制好了,但是没有虚线动画。

2. 虚线实现

观察实现的图中既有实线,也有虚线,所以这儿需要用到 templateMap

定义实线及虚线模板

  1. // 定义集合,存储实线、虚线模板
  2. const templmap = new go.Map()
  3. const color = '#000'
  4. // 默认连线模板
  5. const defaultTemplate = $(
  6. go.Link,
  7. $(go.Shape, { stroke: color, strokeWidth: 1 }),
  8. $(go.Shape, { toArrow: 'Standard', fill: color, stroke: color, strokeWidth: 1 })
  9. )
  10. // 虚线连线模板,关键属性:strokeDashArray: [6, 3]
  11. const dashedTemplate = $(
  12. go.Link,
  13. // name: 'dashedLink',后面动画用到
  14. $(go.Shape, { name: 'dashedLink', stroke: color, strokeWidth: 1, strokeDashArray: [6, 3] }),
  15. $(go.Shape, { toArrow: 'Standard', fill: color, stroke: color, strokeWidth: 1 })
  16. )
  17. templmap.add('', defaultTemplate)
  18. // dashed 为名称,描述时用属性 category: 'dashed' 指定
  19. templmap.add('dashed', dashedTemplate)
  20. diagram.linkTemplateMap = templmap

model 数据找到需要描述为虚线的边,加如属性:category: 'dashed',名称需要和定义模板指定的名称一致

  1. { from: "anhui", to: "shandong", category: 'dashed' },

至此,实线、虚线,都绘制好了。接下来就是最后的动画了。

3. 让虚线动起来

找到虚线,更改属性:strokeDashOffset

有两种方式

方式1:go.Animation,会导致节点端口交互时连线操作有粘粘效果

  1. function animation () {
  2. const animation = new go.Animation();
  3. // 虚线动画
  4. diagram.links.each((link) => {
  5. const dashedLink = link.findObject("dashedLink");
  6. if (dashedLink) {
  7. animation.add(dashedLink, "strokeDashOffset", 10, 0)
  8. }
  9. });
  10. animation.easing = go.Animation.EaseLinear;
  11. // Run indefinitely
  12. animation.runCount = Infinity;
  13. animation.start();
  14. }
  15. animation()

方式2:timeout

  1. function animation () {
  2. const loop = () => {
  3. animationTimer = setTimeout(() => {
  4. const oldskips = diagram.skipsUndoManager;
  5. diagram.skipsUndoManager = true;
  6. // 虚线动画
  7. diagram.links.each((link) => {
  8. const dashedLinkShape = link.findObject("dashedLink");
  9. if (dashedLinkShape) {
  10. const off = dashedLinkShape.strokeDashOffset - 3;
  11. // 设置(移动)笔划划动画
  12. dashedLinkShape.strokeDashOffset = (off <= 0) ? 60 : off;
  13. }
  14. });
  15. diagram.skipsUndoManager = oldskips;
  16. loop();
  17. }, 180);
  18. }
  19. loop()
  20. }
  21. animation()

动画的两种方式,如果没有节点端口连线交互,建议用第一种方式实现,库的动画(可能内部做了优化)。如果想更灵活的控制动画或者第一种实现不了时,那么请用第二种方式。

至此,整个效果就完成了。

二、虚线及虚线动画背后的原理

上面的代码,主要用到了 2 个关键的属性:strokeDashArraystrokeDashOffset

文档上有这么两行说明:

For more information, see Stroke Line Dash Array (w3.org),see Stroke Line Dash Offset (w3.org)

背后就是 canvas,及其两个属性 setLineDashlineDashOffset

参考:

mdn - setLineDah:一个Array数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。

代码示例:

  1. function drawDashedLine(pattern) {
  2. ctx.beginPath();
  3. ctx.setLineDash(pattern);
  4. ctx.moveTo(0, y);
  5. ctx.lineTo(300, y);
  6. ctx.stroke();
  7. y += 20;
  8. }
  9. const canvas = document.getElementById('canvas');
  10. const ctx = canvas.getContext('2d');
  11. let y = 15;
  12. drawDashedLine([]);
  13. drawDashedLine([1, 1]);
  14. drawDashedLine([10, 10]);
  15. drawDashedLine([20, 5]);
  16. drawDashedLine([15, 3, 3, 3]);
  17. drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3]);
  18. drawDashedLine([12, 3, 3]); // Equals [12, 3, 3, 12, 3, 3]

mdn - lineDashOffset:设置虚线偏移量的属性

代码示例:

  1. var canvas = document.getElementById("canvas");
  2. var ctx = canvas.getContext("2d");
  3. var offset = 0;
  4. function draw() {
  5. ctx.clearRect(0,0, canvas.width, canvas.height);
  6. ctx.setLineDash([4, 2]);
  7. ctx.lineDashOffset = -offset;
  8. ctx.strokeRect(10,10, 100, 100);
  9. }
  10. function march() {
  11. offset++;
  12. if (offset > 16) {
  13. offset = 0;
  14. }
  15. draw();
  16. setTimeout(march, 20);
  17. }
  18. march();

三、虚线的一些概念

虚线:(数学概念)以点或者短线画成的断续的线,多用于几何图形或者标记。

为什么虚线称为蚂蚁线?

在图像影像软件中表示选区的动态虚线,因为虚线闪烁的样子像是一群蚂蚁在跑,所以俗称蚂蚁线。

在Photoshop,After Effect等软件中比较常见。

蚂蚁线:动物的一种本能现象,领头的蚂蚁以随机的路线走向食物或洞穴,第二只蚂蚁紧跟其后以相同的路线行走,每一个后来的蚂蚁紧跟前面蚂蚁行走,排成一条线的现象。

虚线的特征:流动性

四、css 绘制边框虚线

利用 css 的 border-style 绘制,有两个属性值:

  • dotted:显示为一系列圆点。标准中没有定义两点之间的间隔大小,视不同实现而定。圆点半径是 border-width 计算值的一半。
  • dashed:显示为一系列短的方形虚线。标准中没有定义线段的长度和大小,视不同实现而定。

具体参考 mdn - border-style

css 原生属性能实现虚线效果,但是要在此基础上实现动画,不容易。但是可以用 css 的其他属性来实现。

示例:

  1. <div class="container">蚂蚁线</div>
  1. .container {
  2. width: 100px;
  3. height: 100px;
  4. padding: 5px;
  5. border: 1px solid transparent;
  6. background: linear-gradient(white, white) padding-box,
  7. repeating-linear-gradient(-45deg, black 0, black, 25%, transparent 0, transparent 50%) 0% 0% / 0.6em 0.6em;
  8. animation: ants 10s linear infinite;
  9. }
  10. @keyframes ants {
  11. to {
  12. background-position: 100% 100%;
  13. }
  14. }

gojs 如何实现虚线(蚂蚁线)动画?的更多相关文章

  1. gojs 实用高级用法

    大家,新年好! 历史文章: 数据可视化 gojs 简单使用介绍 gojs 如何实现虚线(蚂蚁线)动画? 本文介绍的是在使用 gojs 制作图的过程中,你可能会碰到的问题的一些解决方案. gojs 是一 ...

  2. iOS 一个小动画效果-b

    近期工作不忙,来一个需求感觉棒棒的,是一个比较简单的页面,如下图(图1) 图1 应该很简单吧,没什么大的功能,就是一个展示,一个拨打电话,拨打电话不需要说,几行代码搞定,基本UI也不用说了,刚培训完的 ...

  3. WPF炫酷UI及动画

    偶然看见了一张图,感觉挺好看的,花了点时间将他转化成了我代码仓库的一部分.虽然不难但也费时间.其中除了背景是百度的一张底图,其他所有内容均通过WPF的Path.Line.TextBlock.Borde ...

  4. 数据可视化-gojs插件使用技巧总结

    随着云计算时代的到来,由于Web技术的快速革新以及为了提供高质量的用户体验,数据可视化成为了前端技术发展的一大方向.为了解决这个问题,现如今涌现了很多优秀的第三方的javascript图形库,比如hi ...

  5. CSS 奇思妙想边框动画

    今天逛博客网站 -- shoptalkshow,看到这样一个界面,非常有意思: 觉得它的风格很独特,尤其是其中一些边框. 嘿嘿,所以来一篇边框特辑,看看运用 CSS,可以在边框上整些什么花样. bor ...

  6. 像画笔一样慢慢画出Path的三种方法(补充第四种)

    今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...

  7. 用Canvas写桌球游戏!!!

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 昨天上班的时候闲着无事,就用Canvas写了个桌球游戏来玩玩....所以就拿这游戏上来水一发.或许对一些刚学canvas的人有帮助. 话说 ...

  8. 可视化图表库--goJS

    GoJS是Northwoods Software的产品.Northwoods Software创立于1995年,专注于交互图控件和类库.旗下四款产品: GoJS:用于在HTML上创建交互图的纯java ...

  9. 【Web动画】SVG 线条动画入门

    通常我们说的 Web 动画,包含了三大类. CSS3 动画 javascript 动画(canvas) html 动画(SVG) 个人认为 3 种动画各有优劣,实际应用中根据掌握情况作出取舍,本文讨论 ...

随机推荐

  1. set、multiset深度探索

    set/multiset的底层是rb_tree,因此它有自动排序特性.set中的元素不允许重复必须独一无二,key与value值相同,multiset中的元素允许重复. set的模板参数key即为关键 ...

  2. Linux基础命令---ntpq查询时间服务器

    ntpq ntpq指令使用NTP模式6数据包与NTP服务器通信,能够在允许的网络上查询的兼容的服务器.它以交互模式运行,或者通过命令行参数运行. 此命令的适用范围:RedHat.RHEL.Ubuntu ...

  3. ReactiveCocoa操作方法-秩序

    doNext:      执行Next之前,会先执行这个Block doCompleted:      执行sendCompleted之前,会先执行这个Block - (void)doNext { [ ...

  4. MyBatis(3):优化MyBatis配置文件

    一.连接数据库的配置单独放在一个properties文件中 1,创建一个database.properties driver=com.mysql.jdbc.Driver url=jdbc:mysql: ...

  5. 监控网站是否异常的shell脚本

    本节内容:shell脚本监控网站是否异常,如有异常就自动发邮件通知管理员. 脚本检测流程,如下:1,检查网站返回的http_code是否等于200,如不是200视为异常.2,检查网站的访问时间,超过M ...

  6. Linux:spool命令

    格式调整有以下参数: set echo on/off--是否显示脚本中的需要执行的命令 set feedback on/off--是否显示 select 结果之后返回多少行的提示 set linesi ...

  7. APICloud - 提交项目 点击右键 没有git这个选项

    你们是不是也遇到过这个问题,吧项目检出来后,花了很久的时间,好不容易吧项目改完,提交的时候点击鼠标右键,发现git选项没有在里面了,找不到,但是这个问题也不是很常遇到,机率很小,下面我来告诉你们吧 原 ...

  8. java输入/输出流的基本知识

    通过流可以读写文件,流是一组有序列的数据序列,以先进先出方式发送信息的通道. 输入/输出流抽象类有两种:InputStream/OutputStream字节输入流和Reader/Writer字符输入流 ...

  9. 连接opcserver时报错 connecting to OPC Server "****" CoCreateInstance 服务器运行失败

    在普通windows系统连接OPCServer可能会报这样的错,排查很长时间,OPCServer跟Client都运行正常,点号录入也正常. 最后发现,其实是OPCServer 与OPCClient 权 ...

  10. 车载以太网第二弹|测试之实锤-AVB测试实践

    背景 AVB(Audio Video Bridging)音视频桥接,是由IEEE 802.1标准委员会的IEEE AVB任务组制定的一组技术标准,包括精确时钟同步.带宽预留和流量调度等协议规范,用于构 ...