canvas绘制直线并跟随鼠标旋转

效果

575cfbd85796103288ea12cc5fa3ac71

1、canvas及全局变量定义

<canvas id="chartCanvas" class="chartCanvas">
    你的浏览器不支持canvas,请升级你的浏览器
</canvas>

 var canvas = document.getElementById('chartCanvas');
 var ctx = null;
  var startPoint = {
      x: 500,
      y: 300
  };
  var lineLength = 180;
  var mouseInfo = {
      startPoint: {},
      endPoint: {}
  }

2、初始化canvas

function initCanvas() {
     canvas.width = document.body.clientWidth;
     canvas.height = document.body.clientHeight;

     if (canvas.getContext) {
         ctx = canvas.getContext('2d');
     }
 }

3、初始化线条,绘制一段水平直线

function initLine() {
    ctx.lineWidth = 10;
     ctx.beginPath();
     ctx.moveTo(startPoint.x, startPoint.y);
     ctx.lineTo(startPoint.x + lineLength, startPoint.y);
     ctx.strokeStyle = '#000';
     ctx.stroke();
     ctx.closePath();
 }

4、鼠标处理函数

// 初始化鼠标事件
  function initCanvasEvent() {
      canvas.addEventListener("mousedown", handleMouseDown, false);
      canvas.addEventListener("mousemove", handleMouseMove, false);
      canvas.addEventListener("mouseup", handleMouseUp, false);
  }
  
  // 鼠标按下处理函数
  function handleMouseDown(event) {
      mouseInfo.startPoint = {
          x: event.clientX,
          y: event.clientY
      }
  }
 
 // 鼠标移动处理函数
 function handleMouseMove(event) {
      if (JSON.stringify(mouseInfo.startPoint) === "{}") {
          return;
      }
      mouseInfo.endPoint = {
          x: event.clientX,
          y: event.clientY
      }

      let rotate = getRotateByMouseMove(startPoint, mouseInfo.startPoint, mouseInfo.endPoint);
      clearCanvas();
      initLine();
      drawRotateLine(rotate);
  }

// 鼠标松开处理函数
function handleMouseUp() {
      mouseInfo.startPoint = {};
  }

5、获取鼠标移动时,旋转的角度

function getRotateByMouseMove(orgP, startP, endP) {
   const lengthAB = Math.sqrt(diffPow(orgP.x, startP.x) + diffPow(orgP.y, startP.y));
   const lengthAC = Math.sqrt(diffPow(orgP.x, endP.x) + diffPow(orgP.y, endP.y));
   const lengthBC = Math.sqrt(diffPow(startP.x, endP.x) + diffPow(startP.y, endP.y));

   if (lengthAB === 0 || lengthAC === 0 || lengthBC === 0) {
       return 0;
   }
   const cosA = (pow(lengthAB) + pow(lengthAC) - lengthBC * lengthBC) / (2 * lengthAB * lengthAC);
   const angleA = Math.acos(cosA) * 180 / Math.PI;
   if ((startP.x - orgP.x) * (endP.y - orgP.y) - (endP.x - orgP.x) * (startP.y - orgP.y) > 0) {
       return -angleA;
   }
   return angleA;
}

6、获取旋转后点的坐标

function getPointByOffsetAndAngle(point = {}, offset = 0, angle = 0, dl = 1) {
      return {
          x: point.x + offset * dl * (Math.sin(angle * Math.PI / 180)),
          y: point.y + offset * dl * (Math.cos(angle * Math.PI / 180))
      };
  }

7、绘制旋转后的线条

function drawRotateLine(rotate) {
      var pointOne = getPointByOffsetAndAngle(startPoint, 0, 0);
      var pointTwo = getPointByOffsetAndAngle(startPoint, lineLength, 90 + rotate);
      ctx.lineWidth = 10;
      ctx.beginPath();
      ctx.moveTo(pointOne.x, pointOne.y);
      ctx.lineTo(pointTwo.x, pointTwo.y);
      ctx.strokeStyle = 'red';
      ctx.stroke();
      ctx.closePath();
  }

8、其他函数

function clearCanvas() {
    this.ctx.clearRect(0, 0, canvas.width, canvas.height);
 }
 
[video(video-By8qEOIt-1614925459652)(type-youku)(url-https://player.youku.com/embed/XNTExNTQ0MjczMg==)(image-https://m.ykimg.com/054806016041C9DD0000017D8D05454E)(title-575cfbd85796103288ea12cc5fa3ac71)]

function diffPow(x, y) {
     return (x - y) * (x - y);
  }

  function pow(x) {
      return x * x;
  }

实例已上传至csdn,下载地址:https://download.csdn.net/download/zcylyzhi4/15580606

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值