当前位置:首页 > 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 的 data…

vue 实现闪烁

vue 实现闪烁

Vue 实现闪烁效果的方法 方法一:使用 CSS 动画 在 Vue 组件中定义一个闪烁的 CSS 动画,通过绑定 class 或 style 来控制元素的闪烁效果。 <template>…

vue实现tap

vue实现tap

Vue 实现 Tap 事件 在移动端开发中,Tap 事件比 Click 事件更常用,因为 Click 事件有 300ms 延迟。以下是几种在 Vue 中实现 Tap 事件的方法。 使用第三方库 安装…

vue实现addclass

vue实现addclass

Vue 实现动态添加 class 的方法 在 Vue 中动态添加 class 可以通过多种方式实现,以下是常见的几种方法: 使用对象语法 通过绑定一个对象到 :class,可以动态切换 class…

vue 实现评分

vue 实现评分

Vue 实现评分功能 在 Vue 中实现评分功能可以通过多种方式完成,包括使用第三方组件库或自定义实现。以下是两种常见的方法: 使用第三方组件库(如 Element UI) Element UI 提…

vue实现curd

vue实现curd

Vue实现CRUD操作 初始化Vue项目 使用Vue CLI创建新项目,安装必要依赖如axios用于HTTP请求 vue create crud-demo cd crud-demo npm inst…