欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

轻松上手leader-line.js:绘制指引线的全方位教程

最编程 2024-08-02 10:17:12
...

前言

最近产品提了一个在不同dom之间绘制指引线的需求,类似于下面这样。 调研发现leader-line这个用于绘制指引线的库,文档丰富,作者回复issue及时且耐心,这里分享一下库使用总结和踩坑指南。

1、简介

leader-line 是一个用于在 两个 dom或者svg之间绘制指引线的库,线的类型配置项丰富,可以用于实现简单的用户引导,使用说明、组织架构图等。下面是一些示例。

image.png文档 -- github

2、安装

直接<script>安装

<script src="https://cdn.jsdelivr.net/npm/leader-line@1.0.5/leader-line.min.js"></script>

NPM安装

使用此安装方法的时候,由于leader-line未导出构造函数,所以在使用npm i leader-line之后,在工程里面导入会出现找不到的现象。

import LeaderLine from leader-line

// LeaderLine is undefined

所以推荐的做法是将文件下载到本地,然后在文件尾部追加:

export default LeaderLine

image.png

3、使用

leader-line的作用是在两个元素之间绘制指引线,所以它的所有操作就仅限于两个元素,不支持两个元素以上的指引线的绘制。

1、默认连线

const a = document.getElementById('a'),
  b = document.getElementById('b');
 
# 新建连线
new LeaderLine(
  a, b
)

2、改变线的配置

const a = document.getElementById('a'),
  b = document.getElementById('b');


new LeaderLine(
  a, b,
  {
    color:'red', //线的颜色
    size:8, //线的粗细
    dash: true, // 虚线 dash:[2,4]
    endPlug: 'hand', // 线尾类型
    endPlugSize:1, // 线尾尺寸
    startPlug:'disc',// 线头类型
    startPlugSize:2, //线头尺寸
    path:'grid', // 线的类型
    // 更多配置可参见文档
  }
)

leader-line的全部配置参数如下,详细使用可以见文档

new LeaderLine(start,end,
    {
      color:'',
      size: '',
      path:'',
      startSocket: '',
      endSocket: '',
      startSocketGravity:'',
      endSocketGravity: '',
      startPlug: '',
      endPlug: '',
      startPlugColor: '',
      endPlugColor: '',
      startPlugSize: '',
      endPlugSize: '',
      outline: '',
      outlineColor: '',
      outlineSize: '',
      startPlugOutline: '',
      endPlugOutline: '',
      startPlugOutlineColor: '',
      endPlugOutlineColor: '',
      startPlugOutlineSize: '',
      endPlugOutlineSize: '',
      dash: '',
      len: '',
      gap: '',
      animation: '',
      gradient: '',
      startColor: '',
      endColor: '',
      dropShadow: '',
      dx: '',
      dy: '',
      blur: '',
      color: '',
      opacity: '',
    }
)

3、实例方法 new LeaderLine会返回该指引线的实例对象,可以通过该对象方法对指引线进行一些操作,比如控制线的展示隐藏。

const a = document.getElementById('a'),
  b = document.getElementById('b');


const line = new LeaderLine(
  a, b,
  {
    color:'red', //线的颜色
    size:8, //线的粗细
    dash: true, // 虚线 
    endPlug: 'hand', // 线尾类型
    endPlugSize:1, // 线尾尺寸
    startPlug:'disc',// 线头类型
    startPlugSize:2, //线头尺寸
    path:'grid', // 线的类型
    // 更多配置可参见文档
  }
)

const b1 = document.getElementById('b1'),
b2 = document.getElementById('b2')
b1.addEventListener('click',function(){
  line.show()
})
b2.addEventListener('click',function(){
  line.hide()
})
<div id="app">
  <div id="a"></div>
  <div id="b"></div>
  <div>
    <button id="b1">展示</button>
    <button id="b2">隐藏</button>
  </div>
</div>

更多的实例方法如下:
line.position() //重新计算引导线的位置,可用于页面尺寸变化时、容器滚动时,拖动时等
line.setOptions() //动态修改指引线的配置
line.remove() // 从页面中删除指引线 -> 也就是删除生成的svg元素

3、进阶

1、如何在多个dom之间绘制指引线?

由于leader-line仅支持两个dom元素之间绘制指引线,如果想要一个dom元素指向多个不同的dom元,则需要在不同的dom之间绘制分别绘制指引下,比如下面的简单的1对2。

const a = document.getElementById('a'),
  b = document.getElementById('b'),
  c= document.getElementById('c')

const line1 = new LeaderLine(
  a, b
)
const line2 = new LeaderLine(
  a, c
)

需要注意的是:如果连线是虚线的话(path:grid),则可能会出现连续重复的地方变成实线,可以思考一下如何解决,如下图。

我的解决办法是使用(*SocketGravity)改变线的实际位置。效果就是有两根线是没有连接到targetElement上的,只走到了三根指引线的交点处。

2、改变指引线的挂载位置

由于指引线默认被挂载到了body上,且不支持配置(官方说是为了计算位置不出问题),如果想改变挂载位置可以通过如下操作

const elmWrapper = document.getElementById('svg-wrapper') // 想要挂载的节点
const lines = document.getElementsByClassName('leader-line')
elmWrapper.append(...lines)

3、 容器滚动

由于指引线只在实例化的时候计算了一次位置,如果容器滚动,则指引线的位置就会错乱,可以通过监听容器滚动调用line.position()重新计算线的位置。如果线较多的话可能会引起页面卡顿。

其实也是有解决办法的,就是将指引线挂载到滚动容器内就行了,这样就不用重新计算位置了

const scollContainer = document.querySelector('#scroll-container')
      
const elmWrapper = document.getElementById('svg-wrapper')
// 重置svg-wrapper的位置
elmWrapper.style.transform = 'none'
const rectWrapper = elmWrapper.getBoundingClientRect()
elmWrapper.style.transform =
    'translate(' +
    (rectWrapper.left + pageXOffset) * -1 +
    'px, ' +
    (rectWrapper.top + pageYOffset) * -1 +
    'px)'
lineInstances.forEach(instance => {
    instance.position()
})

4、踩坑指南

leader-line默认开启了windowresize的监听,如果想要自定义resize的回调函数或者在vue的页面销毁之前取消resize的监听,可以这样设置。

LeaderLine.positionByWindowResize = false

在vue中如果不取消监听,切换路由时,leader-line依然会在resize的时候重新布局,从而引起报错。

5、总结

各位召唤师如果在使用过程中有什么问题,可以评论区留言,盖伦大王看到就会解答的,毕竟也是逛了很久的issue>