当前位置:首页 > VUE

vue实现canvas拖拽

2026-02-18 20:10:02VUE

Vue 实现 Canvas 拖拽功能

基础 Canvas 设置

在 Vue 中创建一个 Canvas 元素,并初始化绘图上下文:

<template>
  <canvas ref="canvas" @mousedown="startDrag" @mousemove="onDrag" @mouseup="endDrag"></canvas>
</template>

<script>
export default {
  data() {
    return {
      isDragging: false,
      selectedObject: null,
      objects: [
        { x: 100, y: 100, width: 50, height: 50, color: 'red' }
      ]
    }
  }
}
</script>

绘制对象到 Canvas

在 mounted 钩子中初始化 Canvas 并绘制对象:

vue实现canvas拖拽

mounted() {
  this.ctx = this.$refs.canvas.getContext('2d');
  this.drawObjects();
},
methods: {
  drawObjects() {
    this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);
    this.objects.forEach(obj => {
      this.ctx.fillStyle = obj.color;
      this.ctx.fillRect(obj.x, obj.y, obj.width, obj.height);
    });
  }
}

实现拖拽逻辑

添加拖拽相关的事件处理方法:

methods: {
  startDrag(e) {
    const mouseX = e.offsetX;
    const mouseY = e.offsetY;

    this.selectedObject = this.objects.find(obj => 
      mouseX >= obj.x && 
      mouseX <= obj.x + obj.width &&
      mouseY >= obj.y && 
      mouseY <= obj.y + obj.height
    );

    if (this.selectedObject) {
      this.isDragging = true;
      this.dragOffsetX = mouseX - this.selectedObject.x;
      this.dragOffsetY = mouseY - this.selectedObject.y;
    }
  },

  onDrag(e) {
    if (!this.isDragging || !this.selectedObject) return;

    this.selectedObject.x = e.offsetX - this.dragOffsetX;
    this.selectedObject.y = e.offsetY - this.dragOffsetY;
    this.drawObjects();
  },

  endDrag() {
    this.isDragging = false;
    this.selectedObject = null;
  }
}

响应式调整 Canvas 尺寸

添加窗口大小变化时的处理:

vue实现canvas拖拽

mounted() {
  this.resizeCanvas();
  window.addEventListener('resize', this.resizeCanvas);
},
beforeDestroy() {
  window.removeEventListener('resize', this.resizeCanvas);
},
methods: {
  resizeCanvas() {
    const canvas = this.$refs.canvas;
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
    this.drawObjects();
  }
}

性能优化

对于复杂场景,可以使用 requestAnimationFrame 优化渲染:

methods: {
  onDrag(e) {
    if (!this.isDragging || !this.selectedObject) return;

    this.selectedObject.x = e.offsetX - this.dragOffsetX;
    this.selectedObject.y = e.offsetY - this.dragOffsetY;

    if (!this.rafId) {
      this.rafId = requestAnimationFrame(() => {
        this.drawObjects();
        this.rafId = null;
      });
    }
  }
}

触摸屏支持

添加触摸事件处理:

<canvas 
  ref="canvas" 
  @mousedown="startDrag" 
  @mousemove="onDrag" 
  @mouseup="endDrag"
  @touchstart="handleTouchStart"
  @touchmove="handleTouchMove"
  @touchend="handleTouchEnd"
></canvas>
methods: {
  handleTouchStart(e) {
    e.preventDefault();
    const touch = e.touches[0];
    const rect = this.$refs.canvas.getBoundingClientRect();
    this.startDrag({
      offsetX: touch.clientX - rect.left,
      offsetY: touch.clientY - rect.top
    });
  },

  handleTouchMove(e) {
    e.preventDefault();
    const touch = e.touches[0];
    const rect = this.$refs.canvas.getBoundingClientRect();
    this.onDrag({
      offsetX: touch.clientX - rect.left,
      offsetY: touch.clientY - rect.top
    });
  },

  handleTouchEnd() {
    this.endDrag();
  }
}

这个实现提供了完整的 Canvas 拖拽功能,包括鼠标和触摸支持,以及性能优化。可以根据具体需求调整对象检测逻辑或添加更多交互功能。

标签: 拖拽vue
分享给朋友:

相关文章

vue实现菜单栏锚点

vue实现菜单栏锚点

实现锚点菜单的基本思路 在Vue中实现菜单栏锚点功能,主要涉及两个方面:创建可跳转的锚点位置,以及菜单项的点击滚动控制。通过监听滚动事件可以高亮当前可见区域的对应菜单项。 创建页面锚点位置 在需要跳…

vue交互实现

vue交互实现

Vue 交互实现方法 Vue.js 提供了多种方式实现用户交互,包括事件处理、表单绑定、动态渲染等。以下是常见的交互实现方法: 事件处理 通过 v-on 或 @ 指令绑定事件,触发方法或直接执行表达…

vue element实现

vue element实现

Vue Element UI 实现 Vue Element UI 是基于 Vue.js 的组件库,提供丰富的 UI 组件,适合快速开发企业级中后台产品。以下是一些关键实现方法和步骤: 安装 Vue…

vue实现键盘

vue实现键盘

Vue 实现键盘功能 在Vue中实现键盘功能通常涉及监听键盘事件、处理输入以及渲染虚拟键盘界面。以下是几种常见的实现方式: 监听键盘事件 通过@keydown或@keyup指令监听键盘事件,适用于需…

vue实现slidetoggle

vue实现slidetoggle

Vue 实现 SlideToggle 效果 SlideToggle 是一种常见的交互效果,元素以滑动方式展开或收起。以下是几种实现方法: 使用 CSS Transition 和 v-show…

vue实现座位

vue实现座位

Vue实现座位布局 使用Vue实现座位布局可以通过组件化和响应式数据管理来简化开发流程。以下是一个完整的实现方案: 数据准备 定义座位数据结构,通常使用二维数组表示行列关系: data() {…