距离提示辅助线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)
  };
}
相关文章
|
4月前
|
Python
python用鼠标获取图像任一点的坐标和像素值
python用鼠标获取图像任一点的坐标和像素值
152 1
|
4月前
|
API C++ 计算机视觉
【opencv3】鼠标框选矩形并显示当前像素点坐标和矩形中心点坐标C++
【opencv3】鼠标框选矩形并显示当前像素点坐标和矩形中心点坐标C++
|
2月前
|
前端开发
Canvas绘画之三条二次方贝塞尔曲线构成的复选框标记对号
Canvas绘画之三条二次方贝塞尔曲线构成的复选框标记对号
|
3月前
|
存储 Cloud Native Linux
OpenCV鼠标操作(画红色方框截取图像)
OpenCV鼠标操作(画红色方框截取图像)
|
4月前
LabVIEW当鼠标悬停在图形曲线上时显示坐标
LabVIEW当鼠标悬停在图形曲线上时显示坐标
48 1
|
4月前
|
JavaScript 前端开发 流计算
使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理
使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理
|
10月前
Echarts去掉叠堆折线区域图的区域颜色
Echarts去掉叠堆折线区域图的区域颜色
102 0
|
编解码 前端开发 PHP
悬浮坐标解决方案:如何在图片获取xy鼠标位置和增加标注信息
悬浮坐标解决方案:如何在图片获取xy鼠标位置和增加标注信息
132 0
获取 table 距离窗口上方的高度(有深度的文章)
获取 table 距离窗口上方的高度(有深度的文章)
209 0
|
测试技术 Android开发 计算机视觉