• 售前

  • 售后

热门帖子
入门百科

gojs实现蚂蚁线动画效果

[复制链接]
123457443 显示全部楼层 发表于 2022-1-8 04:21:42 |阅读模式 打印 上一主题 下一主题
目次


  • 一、gojs 实现

    • 1. 画图
    • 2. 虚线实现
    • 3. 让虚线动起来

  • 二、虚线及虚线动画背后的原理
  • 三、虚线的一些概念
  • 四、css 绘制边框虚线
在绘制 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. 虚线实现

观察实现的图中既有实线,也有虚线,所以这儿需要用到
  1. 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 数据找到需要形貌为虚线的边,加如属性:
  1. category: &#39;dashed&#39;
复制代码
,名称需要和界说模板指定的名称同等
  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 个关键的属性:strokeDashArray、strokeDashOffset。
文档上有这么两行说明:
For more information, see Stroke Line Dash Array (w3.org),see Stroke Line Dash Offset (w3.org)
背后就是 canvas,及其两个属性
  1. setLineDash
复制代码
  1. lineDashOffset
复制代码
参考:
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实现蚂蚁线动画结果的文章就先容到这了。渴望对各人的学习有所资助,也渴望各人多多支持草根技能分享。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作