距离提示辅助线so easy

简介: 距离提示辅助线so easy!!!距离提示辅助线so easy!!!距离提示辅助线so easy!!!距离提示辅助线so easy!!!

距离提示辅助线

位置与大小格式

{
   
x:100,
y:200,
width:300,
height:400
}

一个点到一个矩形的距离

  • 点到左边

  • 点到右边

  • 点到上边

  • 点到下边

一个矩形与另一个矩形的距离

  • 矩形 1 的左边 vs 矩形 2 的左边,矩形 2 的右边

  • 矩形 1 的右边 vs 矩形 2 的左边,矩形 2 的右边

  • 矩形 1 的上边 vs 矩形 2 的上边,矩形 2 的下边

  • 矩形 1 的下边 vs 矩形 2 的上边,矩形 2 的下边

取矩形 1 每个情况的最小值就是对应边到矩形 2 的距离

function getXDistance(props, rect) {
   
  return [
    Math.abs(rect.x - props.x),
    Math.abs(rect.x + rect.width - props.x),
    Math.abs(rect.x - (props.x + props.width)),
    Math.abs(rect.x + rect.width - (props.x + props.width))
  ];
}
function getYDistance(props, rect) {
   
  return [
    Math.abs(rect.y - props.y),
    Math.abs(rect.y + rect.height - props.y),
    Math.abs(rect.y - (props.y + props.height)),
    Math.abs(rect.y + rect.height - (props.y + props.height))
  ];
}

判断一个矩形是否在附近

参考矩形另一个矩形的距离在 nearD 范围内即在附近,绘制对应的辅助线.
当某个边重合,距离为 0 不进行绘制。

//附近距离
let nearD = 160;
export function setNearDistance(d) {
   
  nearD = d;
}
/**
 * 检查组件是否在选框范围内
 * @param {Object} props 组件位置大小数据
 * @returns {Boolean}
 */
function checkNear(props, rect) {
   
  let xD = getXDistance(props, rect);
  let yD = getYDistance(props, rect);
  if (Math.min(...xD) <= nearD || Math.min(...yD) <= nearD) {
   
    return true;
  }

  return false;
}

interactJs 拖拉拽改变大小和位置

文档地址如下:

https://interactjs.io/docs/

具体代码地址

https://github.com/xiaolidan00/distanceTipLine

策略模式获取最短距离


 const XLine = {
   
  0: (props, rect) => {
   
    return Math.min(rect.x, props.x);
  },
  1: (props, rect) => {
   
    return Math.min(rect.x + rect.width, props.x);
  },
  2: (props, rect) => {
   
    return Math.min(rect.x, props.x + props.width);
  },
  3: (props, rect) => {
   
    return Math.min(rect.x + rect.width, props.x + props.width);
  }
};

const YLine = {
   
  0: (props, rect) => {
   
    return Math.min(rect.y, props.y);
  },
  1: (props, rect) => {
   
    return Math.min(rect.y + rect.height, props.y);
  },
  2: (props, rect) => {
   
    return Math.min(rect.y, props.y + props.height);
  },
  3: (props, rect) => {
   
    return Math.min(rect.y + rect.height, props.y + props.height);
  }
};

当前矩形需要绘制包围框,包括:相对于父容器的上下边界和距离,左右边界,宽高

let posH = [
    //左距离
    {
   
      style: {
   
        left: 0,
        top: top + height * 0.5 - 16 + 'px',
        width: left + 'px'
      },
      value: left
    },
    //右距离
    {
   
      style: {
   
        right: 0,
        top: top + height * 0.5 - 16 + 'px',
        width: screenWidth - (left + width) + 'px'
      },
      value: screenWidth - (left + width)
    },
    //宽度
    {
   
      style: {
   
        left: left + 'px',
        top: top + height * 0.5 - 16 + 'px',
        width: width + 'px',
        justifyContent: 'flex-start',
        border: 'none',
        paddingLeft: '10px'
      },
      value: height
    },
    //上边界
    {
   
      style: {
   
        left: 0,
        top: top + 'px',
        width: '100%',
        borderBottom: 'dashed 1px rgb(37, 124, 245)'
      }
    },
    //下边界
    {
   
      style: {
   
        left: 0,
        top: top + height + 'px',
        width: '100%',
        borderBottom: 'dashed 1px rgb(37, 124, 245)'
      }
    }
  ];
  let posV = [
    //上距离
    {
   
      style: {
   
        left: left + width * 0.5 + 'px',
        top: 0,
        height: top + 'px'
      },
      value: top
    },
    //下距离
    {
   
      style: {
   
        left: left + width * 0.5 + 'px',
        bottom: 0,
        height: screenHeight - (top + height) + 'px'
      },
      value: screenHeight - (top + height)
    },
    //高度
    {
   
      style: {
   
        left: left + width * 0.5 + 'px',
        top: top + 'px',
        height: height + 'px',
        alignItems: 'flex-start',
        border: 'none',

        paddingTop: '10px'
      },
      value: height
    },
    //左边界
    {
   
      style: {
   
        left: left + 'px',
        top: 0,
        height: '100%',
        borderLeft: 'dashed 1px rgb(37, 124, 245)'
      }
    },
    //右边界
    {
   
      style: {
   
        left: left + width + 'px',
        top: 0,
        height: '100%',
        borderLeft: 'dashed 1px rgb(37, 124, 245)'
      }
    }
  ];

获取辅助线:遍历所有组件,对比最短距离,在范围内则加入辅助线



/**
 *
 * @param {Object} activeElement 参考元素
 * @param {Array} elmts 元素list
 * @param {DOM} el 父元素id
 * @returns {Object} {h:横向辅助线,v:纵向辅助线}
 */
export function getGuideLine(activeElement, elmts, el) {
   
  let {
    x: left, y: top, width, height } = activeElement.props;
  let container = document.querySelector(el);
  let screenWidth = container.offsetWidth;
  let screenHeight = container.offsetHeight;
  let posH...
  let posV...
  let nearLineH = [];
  let nearLineV = [];
  elmts.forEach((elmt) => {
   
    if (elmt.id != activeElement.id && checkNear(elmt.props, activeElement.props)) {
   
      //横向距离
      let xD = getXDistance(elmt.props, activeElement.props);

      let isLeft1 = false;
      let isLeft2 = false;
      for (let i = 0; i < xD.length; i++) {
   
        let d = xD[i];
        //去重
        if (i == 2 && isLeft1) {
   
          continue;
        }
        if (i == 3 && isLeft2) {
   
          continue;
        }
        if (d > 0 && d <= nearD) {
   
          let s = XLine[i](elmt.props, activeElement.props, d);
          if (i == 0) {
   
            isLeft1 = true;
          }
          if (i == 1) {
   
            isLeft2 = true;
          }
          nearLineH.push({
   
            style: {
   
              left: s + 'px',
              top: elmt.props.y + elmt.props.height * 0.5 - 16 + 'px',
              width: d + 'px'
            },
            value: d
          });
        }
      }

      let yD = getYDistance(elmt.props, activeElement.props);

      let isTop1 = false;
      let isTop2 = false;
      for (let i = 0; i < yD.length; i++) {
   
        let d = yD[i];
         //去重
        if (i == 2 && isTop1) {
   
          continue;
        }
        if (i == 3 && isTop2) {
   
          continue;
        }
        if (d > 0 && d <= nearD) {
   
          let s = YLine[i](elmt.props, activeElement.props, d);
          if (i == 0) {
   
            isTop1 = true;
          }
          if (i == 1) {
   
            isTop2 = true;
          }
          nearLineV.push({
   
            style: {
   
              left: elmt.props.x + elmt.props.width * 0.5 + 'px',
              top: s + 'px',
              height: d + 'px'
            },
            value: d
          });
        }
      }
    }
  });

  return {
   
    h: posH.concat(nearLineH),
    v: posV.concat(nearLineV)
  };
}
相关文章
|
1月前
|
数据可视化 数据挖掘 数据处理
python 盒装图纵坐标单位
【4月更文挑战第1天】
|
3月前
|
IDE 开发工具
Poco脚本的点击位置与点击偏移
Poco脚本的点击位置与点击偏移
|
3月前
|
算法 IDE 开发工具
Airtest脚本的点击位置与点击偏移
Airtest脚本的点击位置与点击偏移
|
5月前
|
存储 计算机视觉 索引
OpenCV中确定像素位置及获取、修改像素BGR值讲解及演示(Python实现 附源码)
OpenCV中确定像素位置及获取、修改像素BGR值讲解及演示(Python实现 附源码)
70 0
Easy X显示控制台数据
在initgraph里面加上EX_SHOWCONSOLE
59 0
|
存储 数据处理 Python
python--对站点数据做EOF并做插值绘制填色图
最近,师弟在学习使用python复现毕设论文,正好之前没有处理过站点数据,也没咋用过EOF,特此记录下使用python处理站的数据的过程。
python--对站点数据做EOF并做插值绘制填色图
python 如何绘制浮动区间
最近,在阅读文献时,发现有一个图涉及到均值以及相对均值标准差浮动区间的问题,感觉比较有意思,特此记录一下学习过程。
python 如何绘制浮动区间
|
easyexcel
使用easyexcel导出时行高不自动调整的解决
使用easyexcel导出时行高不自动调整的解决
1053 0
使用easyexcel导出时行高不自动调整的解决
Codeforces1486 C1.Guessing the Greatest (easy version)(交互题+二分)
Codeforces1486 C1.Guessing the Greatest (easy version)(交互题+二分)
73 0
【pyqt5】line edit实时获取输入值
【pyqt5】line edit实时获取输入值