[技术分享]Vue-Draggable-Resizable-Rotatable 组件实现原理

zuimeiaj发布于2 个月前 • 130 次阅读

A vue component that can be rotated and resized

最近把yoyoo原型设计中的核心拖拽缩放组件整理了下,并开源到了github上,基于vue cli3开发,支持pc端和移动端

该组件的思路主要是基于控制点所对应的对角来完成缩放,

在缩放组件时,鼠标点击一个控制点开始缩放,此时会先计算该鼠标位置的初始角度,和对角线(斜边)的长度

image

当鼠标移动的时候我们就可以实时的得到最新的角度,和斜边长度,以此来计算出矩形的宽高。此时我们就可以得到一个变化后的矩形大小

image

这个时候我们已经得到矩形的新的大小,但是由于组件基于中心点旋转,当旋转后改变矩形的大小。其实际的 x 和 y 已经发生了变化,这里需要将控制点的对角点固定,利用矩阵点乘获取矩形在平面上的实际坐标点得到 移动增量(deltaX,deltaY),减去移动增量就能将矩形固定到原来的位置。 image

兼容移动端

移动端主要是在支持一下触摸事件就可以了。和pc一样,添加相应的touch事件,并在事件中判断 touches属性 如果有则取第一个作为事件对象就行了


handler(event){
  const point = event.touches ? event.touches[0]: event
  const {clientX,clientY} = point
}

组件的旋转

//使用基本的三角函数就可以啦,获取矩形的中心点使用getBoundingClientRect()得到矩形的相对于屏幕边缘的位置和大小
const rect = getBoundingClientRect()
const cx = react.left + rect.width /2 
const cy = rect.top + rect.height/2
const startAngle = Math.atan2(pageX - cy,pageY - cx)

// 在移动的时候实时计算当前的角度并减去初始角度就能得到移动的角度了
const currentAngle = Math.atan2(pageX - cy,pageY - cx)
const rotation = currentAngle - startAngle 

欢迎指教

共收到 0 条回复