github.com/jasondu/wx-…javascript
因为movable-view没法实现旋转,因此选择使用canvasjava
看起来挺简单的嘛,就把上面这几个问题解决了,就能够实现功能了;接下来咱们一一解决。git
定义一个DragGraph类,传入元素的各类属性(坐标、尺寸…)实例化后推入一个渲染数组里,而后再循环这个数组调用实例中的渲染方法,这样就能够把多个元素渲染到canvas上了。github
在DragGraph类中定义了判断点击位置的方法,咱们在canvas上绑定touchstart事件,将手指的坐标传入上面的方法,咱们就能够知道手指是点击到元素自己,仍是删除图标或者变换大小的图标上了,这个方法具体怎么判断后面会讲解。canvas
经过循环渲染数组判断是非点击到哪一个元素到,若是点击中了多个元素,也就是多个元素重叠,那第一个元素就是最上层的元素啦。数组
###如何实现拖拽元素ui
经过上面咱们能够判断手指是否在元素上,当touchstart事件触发时咱们记录当前的手指坐标,当touchmove事件触发时,咱们也知道这时的坐标,两个坐标取差值,就能够得出元素位移的距离啦,修改这个元素实例的x和y,再从新循环渲染渲染数组就能够实现拖拽的功能。this
这一步相对比较难一点,我会经过示意图跟你们讲解。spa
咱们先讲缩放和旋转code
经过touchstart和touchmove咱们能够得到旋转前的旋转后的坐标,图中的线A为元素的中点和旋转前点的连线;线B为元素中点和旋转后点的连线;咱们只须要求A和B两条线的夹角就能够知道元素旋转的角度。缩放尺寸为A和B两条线长度之差。
计算旋转角度的代码以下:
const centerX = (this.x + this.w) / 2; // 中点坐标
const centerY = (this.y + this.h) / 2; // 中点坐标
const diffXBefore = px - centerX; // 旋转前坐标
const diffYBefore = py - centerY; // 旋转前坐标
const diffXAfter = x - centerX; // 旋转后坐标
const diffYAfter = y - centerY; // 旋转后坐标
const angleBefore = Math.atan2(diffYBefore, diffXBefore) / Math.PI * 180;
const angleAfter = Math.atan2(diffYAfter, diffXAfter) / Math.PI * 180;
// 旋转的角度
this.rotate = currentGraph.rotate + angleAfter - angleBefore;
复制代码
计算缩放尺寸的代码以下:
// 放大 或 缩小
this.x = currentGraph.x - (x - px);
this.y = currentGraph.y - (x - px);
复制代码