js从某点开始拉伸一条线

核心思路

根据起始点的x,y轴坐标与当前鼠标所在的x,y轴坐标之间生成一个宽度与旋转角度不断变化的div模拟一条线

也可使用宽度不变高度改变方式模拟线的长度

line.style.width = Math.sqrt((moveX - x) * (moveX - x) + (moveY - y) *
(moveY - y)) + “px”;
line.style.transform = “rotate(” + Math.atan2(moveY - y, moveX - x) + “rad)”;

方法实现

// 默认样式
const defaultStyle = {
  height: '2px',
  background: 'red',
  backgroundSize: '8px 1px',
  transformOrigin: 'top lefT',
  zIndex: 9999,
  pointerEvents: 'none',
  linearGradient: '',
};

/**
  ele:传入的dom容器
  x: 起始x轴坐标
  y: 其实y轴坐标
  fn: 回调函数
  style: 样式
*/
// 鼠标按下不放开,从按下点到移动点之间实时生成一条线
// 样式可以完全抽离进行自定义
const startDraw = (ele, x, y, fn, style = defaultStyle) => {
    ele = isDOMElement(ele) ? ele : ele.current;
    const { background, height, backgroundSize, transformOrigin, zIndex, pointerEvents, linearGradient: oldLinearGradient } = style;
    const linearGradient = `linear-gradient(to right, ${background} 0%, transparent 50%, transparent 100%)`;
    const move = (e) => {
      const moveX = e.clientX;
      const moveY = e.clientY;
      const line = document.getElementById('line') === null ? document.createElement("div") : document.getElementById('line')
      line.id = "line";
      line.style.position = "absolute";
      line.style.left = x + "px";
      line.style.top = y + "px";
      line.style.width = Math.sqrt((moveX - x) * (moveX - x) + (moveY - y) * (moveY - y)) + "px";
      line.style.height = height;
      line.style.background = oldLinearGradient ? oldLinearGradient : linearGradient;
      line.style.backgroundSize = backgroundSize;
      line.style.transformOrigin = transformOrigin;
      line.style.transform = "rotate(" + Math.atan2(moveY - y, moveX - x) + "rad)";
      line.style.zIndex = zIndex;
      line.style.pointerEvents = pointerEvents;
      ele.appendChild(line);
    }
    ele.addEventListener('mousemove', move);
    document.addEventListener('mouseup', () => {
      fn && fn();
      document.getElementById('line') && document.getElementById('line').remove();
      ele.removeEventListener('mousemove', move);
    });
}

具体代码应用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="demo" style="background-color: #ebebeb;z-index:0;position:absolute;width:1400px;height:600px;"></div>
</body>
<script>

// 判断是否为dom
function isDOMElement(obj) {
  return obj instanceof HTMLElement && typeof obj.nodeType === 'number';
}

const defaultStyle = {
  height: '2px',
  background: 'red',
  backgroundSize: '8px 1px',
  transformOrigin: 'top lefT',
  zIndex: 9999,
  pointerEvents: 'none',
  linearGradient: '',
};
const startDraw = (ele, x, y, fn, style = defaultStyle) => {
    ele = isDOMElement(ele) ? ele : ele.current;
    const { background, height, backgroundSize, transformOrigin, zIndex, pointerEvents, linearGradient: oldLinearGradient } = style;
    const linearGradient = `linear-gradient(to right, ${background} 0%, transparent 50%, transparent 100%)`;
    const move = (e) => {
      const moveX = e.clientX;
      const moveY = e.clientY;
      const line = document.getElementById('line') === null ? document.createElement("div") : document.getElementById('line')
      line.id = "line";
      line.style.position = "absolute";
      line.style.left = x + "px";
      line.style.top = y + "px";
      line.style.width = Math.sqrt((moveX - x) * (moveX - x) + (moveY - y) * (moveY - y)) + "px";
      line.style.height = height;
      line.style.background = oldLinearGradient ? oldLinearGradient : linearGradient;
      line.style.backgroundSize = backgroundSize;
      line.style.transformOrigin = transformOrigin;
      line.style.transform = "rotate(" + Math.atan2(moveY - y, moveX - x) + "rad)";
      line.style.zIndex = zIndex;
      line.style.pointerEvents = pointerEvents;
      ele.appendChild(line);
    }
    ele.addEventListener('mousemove', move);
    document.addEventListener('mouseup', () => {
      fn && fn();
      document.getElementById('line') && document.getElementById('line').remove();
      ele.removeEventListener('mousemove', move);
    });
}

document.getElementById('demo').onmousedown = function(e) {
    const x = e.clientX;
    const y = e.clientY;
    startDraw(document.getElementById('demo'), x, y)
}

</script>
</html>

具体效果展示
在这里插入图片描述

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值