常用的第三方组件
-
vue-drag-resize
2.vue-draggable-resizeable
自己手写一个自定义拖曳&缩放组件
/**
* @author ddwei
* @description 拖拽缩放插件
*/
export default class Drag_scale {
constructor(target, options) {
this._init(target, options);
}
/**
* 初始化绑定节点
* @param {HTMLElement|String} target 目标元素
* @param {Object} options 选项
*/
_init(target, options) {
if (!target) throw new Error("el为必填项");
this.el =
typeof target === "string" ? document.querySelector(target) : target;
this._defaultOptions = {
rotate: 0, // 图旋转角度
minScale: 1, // 最小缩放比例
maxScale: 3 // 最大缩放比例
};
this.options = {
...this._defaultOptions,
...options
};
// 缩放
this.maxScale = this.options.maxScale;
this.minScale = this.options.minScale;
this.scale = this.options.scale || 1; // 初始缩放比例设置为1
// 拖拽
this.dragTransformX = 0;
this.dragTransformY = 0;
//拖拽历史点
this.lastDragPoint = {
x: 0,
y: 0
};
this.rotate = this.options.rotate;
this.eventList = [
{
name: "mousemove",
handler: this._handleDragMove.bind(this)
}
];
// 绑定事件对象
this.el.addEventListener("mousedown", e => {
this._handleDragStart(e);
this.eventList.forEach(({ name, handler }) => {
this.el.addEventListener(name, handler, false);
});
});
// 鼠标抬起解绑move事件
this.el.addEventListener("mouseup", e => {
this._cleanEvent(this.eventList);
});
}
/**
* 处理缩放,旋转,拖拽
*/
_setTransform(x, y, scale, rotate, transition = false) {
if (!this.el) return;
const text = `transform:scale(${scale}) rotate(${rotate}deg) translate3d(${x}px,${y}px,0);transform-origin:center;)`;
const cssText = transition ? text + "transition:0.3s;" : text;
this.el.setAttribute("style", cssText);
}
/**
* 设置缩放比例
* @param {Number} scale 缩放比例
*/
setScale(scale) {
let s = parseFloat(scale);
if (isNaN(s)) return;
if (s < this.minScale) s = this.minScale;
if (s > this.maxScale) s = this.maxScale;
this.scale = s;
this._setTransform(
this.dragTransformX,
this.dragTransformY,
this.scale,
this.rotate
);
}
/**
* scale + 0.1
*/
makeScaleAddZeroPointOne() {
let newScale = this.scale + 0.1;
this.setScale(newScale);
}
/**
* scale - 0.1
*/
makeScaleSubtractZeroPointOne() {
let newScale = this.scale - 0.1;
this.setScale(newScale);
}
/**
* 旋转api
* @param {Number} direction 方向 1顺时针 -1逆时针
*/
rotateHandler(direction = 1) {
if (![1, -1].includes(direction)) return;
this.rotate = this.rotateFormat(this.rotate + direction * 90);
this._setTransform(
this.dragTransformX,
this.dragTransformY,
this.scale,
this.rotate
);
}
/**
* 旋转角度处理
* @return {Number} 旋转角
*/
rotateFormat(angle) {
if (typeof angle !== "number" || isNaN(angle)) return;
const temp = angle % 360;
const newAngle = temp < 0 ? temp + 360 : temp;
return Math.abs(newAngle);
}
// 解绑事件
_cleanEvent(eventList) {
if (!this.el || eventList.length == 0) return;
eventList.forEach(({ name, handler }) => {
this.el.removeEventListener(name, handler, false);
});
}
/**
* 处理指针结束
* @param {MouseEvent|TouchEvent} e 事件对象
* @returns void
*/
_handlePointerEnd(e) {
// 解绑相关事件
this._cleanEvent(this.eventList);
}
/**
* 获取事件相对触发对象的偏移值
* @param {MouseEvent|TouchEvent} e 事件对象
* @returns 偏移值对象
*/
_getPointOffset(e) {
if (e instanceof MouseEvent) {
return {
x: e.offsetX,
y: e.offsetY
};
} else if (e instanceof TouchEvent) {
const { touches, target } = e;
const { clientX, clientY } = touches[0];
const { left, top } = target.getBoundingClientRect();
return {
x: clientX - left,
y: clientY - top
};
}
}
/**
* 处理拖拽开始
*/
_handleDragStart(e) {
this.lastDragPoint = this._getPointOffset(e);
}
/**
* 处理拖拽移动
*/
_handleDragMove(e) {
const { x, y } = this._getPointOffset(e);
const { x: lastX, y: lastY } = this.lastDragPoint;
this.dragTransformX += x - lastX;
this.dragTransformY += y - lastY;
this._setTransform(
this.dragTransformX,
this.dragTransformY,
this.scale,
this.rotate
);
}
// 绑定事件对象
_bindEvent() {
// this._handleDragStart = this._handleDragStart.bind(this)
// this._handleDragMove = this._handleDragMove.bind(this)
// this._handlePointerEnd = this._handlePointerEnd.bind(this)
}
}
new Drag_scale($el)
网友评论