前面,本示例实现了折线连接线,简述了实现的思路和原理,也已知了一些缺陷。本章将处理一些缺陷的同时,实现支持连接点的自定义,一个节点可以定义多个连接点,最终可以满足类似图元接线的效果。
请大家动动小手,给我一个免费的 Star 吧~
大家如果发现了 Bug,欢迎来提 Issue 哟~
一些调整
- 把示例素材从 src 转移至 public 目录,拖入画布的素材改为异步加载
- 移除部分示例素材
- 一些开发过程中的测试用例可以在线加载
此前有些朋友说导入、导出有异常,估计是线上版本和线下版本的构建示例素材的文件 hash 后缀不一样,跨环境导入、导出无法加载图片导致的。现在调整后就应该正常了。
自定义连接点
先说明一下定义:
// src/Render/types.ts
export interface AssetInfoPoint {
x: number
y: number
direction?: 'top' | 'bottom' | 'left' | 'right' // 人为定义连接点属于元素的什么方向
}
export interface AssetInfo {
url: string
points?: Array<AssetInfoPoint>
}
// src/Render/draws/LinkDraw.ts
// 连接点
export interface LinkDrawPoint {
id: string
groupId: string
visible: boolean
pairs: LinkDrawPair[]
x: number
y: number
direction?: 'top' | 'bottom' | 'left' | 'right' // 人为定义连接点属于元素的什么方向
}
一个素材除了原来的 url 信息外,增加了一个 points 的连接点数组,每个 point 除了记录了它的相对于素材的位置 x、y,还有方向的定义,目的是说明该连接点出入口方向,例如:
做这个定义的原因是,连接方向不可以预知,是与图元的含义有关。
不设定 direction 的话,就代表连接线可以从上下左右4个方向进出,如:
自定义连接点是人为定义的,在这里是手写坐标点,如:
最佳实践应该另外实现一个连接点定义工具(也许后面有机会实现一个),多多支持~
// src/App.vue
// 从 public 加载静态资源 + 自定义连接点
const assetsModules: Array<Types.AssetInfo> = [
{
"url": "./img/svg/ARRESTER_1.svg", points: [{
x: 101, y: 1, direction: 'top' }, {
x: 101, y: 199, direction: 'bottom' }] },
{
"url": "./img/svg/ARRESTER_2.svg", points: [{
x: 101, y: 1, direction: 'top' }, {
x: 101, y: 199, direction: 'bottom' }] },
{
"url": "./img/svg/ARRESTER_2_1.svg", points: [{
x: 101, y: 1, direction: 'top' }, {
x: 101, y: 199, direction: 'bottom' }] },
{
"url": "./img/svg/BREAKER_CLOSE.svg", points: [{
x: 100, y: 1, direction: 'top' }, {
x: 100, y: 199, direction: 'bottom' }] },
{
"url": "./img/svg/BREAKER_OPEN.svg", points: [{
x: 100, y: 1, direction: 'top' }, {
x: 100, y: 199, direction: 'bottom' }] },
// 略
]
素材拖入之前,需要携带 points 信息:
// src/App.vue
function onDragstart(e: GlobalEventHandlersEventMap['dragstart'], item: Types.AssetInfo) {
if (e.dataTransfer) {
e.dataTransfer.setData('src', item.url)
e.dataTransfer.setData('points', JSON.stringify(item.points)) // 传递连接点信息
e.dataTransfer.setData('type', item.url.match(/([^./]+)\.([^./]+)$/)?.[2] ?? '')
<