vue3使用canvas画动态虚线和普通虚线

1、使用ref封装虚线方法

const drawDashed = (
    x: any,
    y: any,
    x1: any,
    y1: any,
    color: any,
    width: any,
    canvas: any
  ) => {
    const ctx = canvas.value.getContext("2d");
    ctx.lineWidth = width;
    ctx.strokeStyle = color;
    ctx.beginPath();
    ctx.setLineDash([5, 15]);
    ctx.moveTo(x, y);
    ctx.lineTo(x1, y1);
    ctx.stroke();
    ctx.closePath();
  };

2、使用dom封装画虚线方法

const drawDashedById = (
    x: any,
    y: any,
    x1: any,
    y1: any,
    color: any,
    width: any,
    ctx: any
  ) => {
    ctx.lineWidth = width;
    ctx.strokeStyle = color;
    ctx.beginPath();
    ctx.setLineDash([5, 15]);
    ctx.moveTo(x, y);
    ctx.lineTo(x1, y1);
    ctx.stroke();
    ctx.closePath();
  };

3、使用ref封装动态虚线

const drawDashedRun = (
    x: any,
    y: any,
    x1: any,
    y1: any,
    color: any,
    width: any,
    canvas: any
  ) => {
    const ctx = canvas.value.getContext("2d");
    // 设置起始偏移量
    let offSet = 0;
    drawDashedRun();
    function drawDashedRun() {
      // const ctx = canvas.value.getContext("2d");
      // 清除矩形内所有内容
      ctx.clearRect(x, y - 1, 95, 10);
      // 开始一次绘制
      ctx.beginPath();
      // 设置虚线4-2-4-2排列
      ctx.setLineDash([4, 2]);
      // 设置虚线偏移量
      ctx.lineDashOffset = -offSet;
      // 绘制圆形
      // ctx.arc(300, 300, 80, 0, Math.PI * 2);
      ctx.moveTo(x, y);
      ctx.lineTo(x1, y1);
      ctx.strokeStyle = color; //在着色之前设置颜色
      ctx.lineWidth = width; //在着色之前设置线宽
      // 执行绘制
      ctx.stroke();
      // 关闭此次绘制
      ctx.closePath();
      // 当偏移量大于16时重归0
      if (offSet > 16) {
        offSet = 0;
      }
      offSet++;
      // 通过setTimeout递归调用绘制
      setTimeout(drawDashedRun, 20);
    }
  };

4、使用dom封装动态虚线

 const drawDashedRunById = (
    x: any,
    y: any,
    x1: any,
    y1: any,
    color: any,
    width: any,
    ctx: any
  ) => {
    // 设置起始偏移量
    let offSet = 0;
    drawDashedRun();
    function drawDashedRun() {
      // const ctx = canvas.value.getContext("2d");
      // 清除矩形内所有内容
      ctx.clearRect(x, y - 1, 95, 10);
      // 开始一次绘制
      ctx.beginPath();
      // 设置虚线4-2-4-2排列
      ctx.setLineDash([4, 2]);
      // 设置虚线偏移量
      ctx.lineDashOffset = -offSet;
      // 绘制圆形
      // ctx.arc(300, 300, 80, 0, Math.PI * 2);
      ctx.moveTo(x, y);
      ctx.lineTo(x1, y1);
      ctx.strokeStyle = color; //在着色之前设置颜色
      ctx.lineWidth = width; //在着色之前设置线宽
      // 执行绘制
      ctx.stroke();
      // 关闭此次绘制
      ctx.closePath();
      // 当偏移量大于16时重归0
      if (offSet > 16) {
        offSet = 0;
      }
      offSet++;
      // 通过setTimeout递归调用绘制
      setTimeout(drawDashedRun, 20);
    }
  };

5、使用ref封装椭圆方法

const drawtuocircle = (
    canvas: any,
    x: any,
    y: any,
    a: any,
    b: any,
    color: any
  ) => {
    const ctx = canvas.value.getContext("2d");
    ctx.save();
    const r = a > b ? a : b;
    const ratioX = a / r;
    const ratioY = b / r;
    ctx.scale(ratioX, ratioY);
    ctx.beginPath();
    ctx.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI, false);
    ctx.closePath();
    ctx.restore();
    ctx.fillStyle = color;
    ctx.fill();
  };
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
同样可以实现,以下是 Vue 3 的示例代码: ``` <template> <canvas ref="canvas"></canvas> </template> <script> import { ref, onMounted } from 'vue'; export default { setup() { const canvasRef = ref(null); const rect = ref(null); const isDragging = ref(false); let offsetX = 0; let offsetY = 0; let ctx; const onMouseDown = (e) => { const rect = canvasRef.value.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; if (rect.value && isInsideRect(x, y)) { isDragging.value = true; offsetX = x - rect.value.x; offsetY = y - rect.value.y; } else { rect.value = { x, y, width: 0, height: 0 }; } }; const onMouseMove = (e) => { if (isDragging.value) { const rect = canvasRef.value.getBoundingClientRect(); const x = e.clientX - rect.left - offsetX; const y = e.clientY - rect.top - offsetY; rect.value.x = x; rect.value.y = y; redraw(); } }; const onMouseUp = () => { if (isDragging.value) { isDragging.value = false; animateRect(); } }; const redraw = () => { ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height); if (rect.value) { ctx.fillStyle = '#f00'; ctx.fillRect(rect.value.x, rect.value.y, rect.value.width, rect.value.height); } }; const animateRect = () => { const start = performance.now(); const end = start + 500; const from = { x: rect.value.x, y: rect.value.y }; const to = { x: 100, y: 100 }; const animate = () => { const now = performance.now(); const progress = (now - start) / (end - start); if (progress >= 1) { rect.value.x = to.x; rect.value.y = to.y; redraw(); } else { const x = from.x + (to.x - from.x) * progress; const y = from.y + (to.y - from.y) * progress; rect.value.x = x; rect.value.y = y; redraw(); requestAnimationFrame(animate); } }; animate(); }; const isInsideRect = (x, y) => { return x >= rect.value.x && x <= rect.value.x + rect.value.width && y >= rect.value.y && y <= rect.value.y + rect.value.height; }; onMounted(() => { const canvas = canvasRef.value; ctx = canvas.getContext('2d'); canvas.width = 600; canvas.height = 400; canvas.addEventListener('mousedown', onMouseDown); canvas.addEventListener('mousemove', onMouseMove); canvas.addEventListener('mouseup', onMouseUp); canvas.addEventListener('mouseleave', onMouseUp); }); return { canvasRef, }; }, }; </script> ``` 在这个示例中,我们使用Vue 3 的 Composition API,使用了 `ref` 来创建响应式数据,并在 `setup` 函数中定义了事件处理函数。其余的代码跟 Vue 2 的示例基本相同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值