当前位置:首页 > VUE

vue实现拖拽旋转

2026-01-17 18:15:37VUE

Vue 实现拖拽旋转

核心思路

通过监听鼠标事件计算旋转角度,结合 CSS 的 transform: rotate() 实现旋转效果。需要处理 mousedownmousemovemouseup 事件,并计算元素中心点与鼠标位置的夹角变化。

实现步骤

模板部分

<template>
  <div class="container">
    <div 
      class="rotatable-element"
      ref="element"
      :style="{ transform: `rotate(${angle}deg)` }"
      @mousedown="startRotate"
    ></div>
  </div>
</template>

脚本部分

vue实现拖拽旋转

<script>
export default {
  data() {
    return {
      angle: 0,
      startAngle: 0,
      isRotating: false,
      center: { x: 0, y: 0 }
    }
  },
  methods: {
    getElementCenter(el) {
      const rect = el.getBoundingClientRect()
      return {
        x: rect.left + rect.width / 2,
        y: rect.top + rect.height / 2
      }
    },
    calculateAngle(center, mouseX, mouseY) {
      return Math.atan2(mouseY - center.y, mouseX - center.x) * 180 / Math.PI
    },
    startRotate(e) {
      this.center = this.getElementCenter(this.$refs.element)
      this.startAngle = this.calculateAngle(this.center, e.clientX, e.clientY) - this.angle
      this.isRotating = true
      document.addEventListener('mousemove', this.rotate)
      document.addEventListener('mouseup', this.stopRotate)
    },
    rotate(e) {
      if (!this.isRotating) return
      const currentAngle = this.calculateAngle(this.center, e.clientX, e.clientY)
      this.angle = currentAngle - this.startAngle
    },
    stopRotate() {
      this.isRotating = false
      document.removeEventListener('mousemove', this.rotate)
      document.removeEventListener('mouseup', this.stopRotate)
    }
  }
}
</script>

样式部分

<style>
.rotatable-element {
  width: 100px;
  height: 100px;
  background-color: #42b983;
  cursor: grab;
  user-select: none;
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center;
}
.container {
  position: relative;
  height: 300px;
  border: 1px dashed #ccc;
}
</style>

优化方向

边界处理 添加角度限制逻辑,例如限制旋转范围为 0-360 度:

vue实现拖拽旋转

rotate(e) {
  if (!this.isRotating) return
  let currentAngle = this.calculateAngle(this.center, e.clientX, e.clientY)
  this.angle = (currentAngle - this.startAngle + 360) % 360
}

性能优化 使用 requestAnimationFrame 替代直接的事件处理:

rotate(e) {
  if (!this.isRotating) return
  requestAnimationFrame(() => {
    const currentAngle = this.calculateAngle(this.center, e.clientX, e.clientY)
    this.angle = currentAngle - this.startAngle
  })
}

触摸屏支持 添加触摸事件处理:

<div 
  @mousedown="startRotate"
  @touchstart="handleTouchStart"
></div>
handleTouchStart(e) {
  const touch = e.touches[0]
  this.startRotate({
    clientX: touch.clientX,
    clientY: touch.clientY
  })
}

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

相关文章

vue交互实现

vue交互实现

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

vue实现曲线

vue实现曲线

Vue 实现曲线的方法 在 Vue 中实现曲线可以通过多种方式,包括使用 SVG、Canvas 或第三方库如 D3.js、ECharts 等。以下是几种常见的方法: 使用 SVG 绘制曲线 SVG…

vue实现反馈

vue实现反馈

Vue 实现反馈功能的方法 在 Vue 中实现反馈功能可以通过多种方式,包括弹窗提示、Toast 消息、表单提交等。以下是几种常见的实现方法。 弹窗反馈 使用 Vue 的组件化特性创建一个弹窗组件,…

vue实现绘图

vue实现绘图

Vue 实现绘图的方法 在 Vue 中实现绘图功能,可以通过多种方式实现,包括使用原生 HTML5 Canvas、第三方库(如 Fabric.js、Konva.js)或 SVG。以下是几种常见的实现方…

vue 实现登录验证

vue 实现登录验证

Vue 实现登录验证的方法 使用 Vue Router 进行路由守卫 在 Vue 项目中,可以通过 Vue Router 的路由守卫(Navigation Guards)实现登录验证。路由守卫可以在路…

vue实现吸附效果

vue实现吸附效果

Vue实现吸附效果的方法 吸附效果通常指页面滚动时,某个元素固定在特定位置(如顶部或底部)。以下是几种实现方式: 使用CSS的position: sticky 通过CSS的sticky定位实现吸附效…