手动实现一个可拖动的画布

想学习可视化,做一个可编辑的可视化工具已经很久了,一个可拖动和缩放的画布是很有必要,在参考了gridstackjs 后作出一个简单的可拖拽和缩放的画布。
 
画布初始化
首先完成画布的大致功能结构,主要是利用mousedown,mousemove,mouseup来记录鼠标的位置信息,并触发初始化传入的钩子。
import _ from "lodash";
import $ from "jquery";
import "./index.css";
const defaults = {    // 传入参数格式
// widget_selector: ".dragger",
// draggable: {
// resizeStart:()=>{实现一个可拖动的画布
// },
// onResize: datas => {
// console.log(datas);
// },
// onStop: () => {}
// },
// resizeable: {
// onStart: () => {},
// onDrag: datas => {
// console.log(datas);
// },
// onStop: () => {}
// }
};
 
class Draggle {
constructor(el, options) {
this.options = _.merge({}, defaults, options);
this.$document = $(document);
this.$container = $(el); // 容器
this.$player = null; // 选中组件
this.isMoving = false;
this.isResizing = false;
this.$widgets = this.$container.children(this.options.widget_selector); // 可拖动组件
this.$resHandles = this.$container.find(this.options.resizeable.handle); // 组件的缩放拖拽图标
this.init();
}
 
 
init() {
this.$document.on("mousemove", e => {});
this.$document.on("mouseup", e => {});
 
this.$widgets.on("mousedown", e => {   
// 这里用箭头函数避免this指向被替换(this始终保持指向Draggle实例)
});
 
this.$resHandles.on("mousedown", e => {  // 右下角拖拽图标
e.stopPropagation();
});
}
}

 

鼠标mousedown事件主要作用在两个dom上,组件和组件的拉伸拖拽图标,作用都是为了标记选中项,记录开始拖拽的时候鼠标的位置或者组件尺寸信息,以及触发钩子
注意:这里需要注意this的只想问题,由于函数的原因,this并没有指向点击的dom元素。
this.$widgets.on("mousedown", e => {
// 这里用箭头函数避免this指向被替换(this始终保持指向Draggle实例)
this.$player = $(e.currentTarget);
this.el_init_pos = this.get_actual_pos(this.$player);
this.mouse_init_pos = this.get_mouse_pos(e);
this.offset_pos = {
x: this.mouse_init_pos.left - this.el_init_pos.left,
y: this.mouse_init_pos.top - this.el_init_pos.top
};
this.isMoving = true;
this.dragStart();
});
 
this.$resHandles.on("mousedown", e => { // 右下角拖拽图标
e.stopPropagation();
this.$player = $(e.currentTarget).parent();
this.isResizing = true;
this.mouse_init_pos = this.get_mouse_pos(e);
this.el_init_size = this.get_actual_size(this.$player);
this.resizeStart();
});
 
document的mousemove事件用于获取实时的位置和尺寸信息,触发组件的缩放和拖拽的实现
this.$document.on("mousemove", e => {
if (this.isMoving) {
const posix = !this.$player ? { x: 0, y: 0 } : this.getWidgetOffset(e);
this.dragging(posix);
} else if (this.isResizing) {
const size = !this.$player ? { w: 100, h: 100 } : this.getWidgetSize(e);
this.resizing(size);
}
});

 

document的mouseup事件用于触发拖拽缩放的结束钩子
this.$document.on("mouseup", e => {
if (this.isMoving) {
this.isMoving = false;
this.$player = null;
const posix = this.getWidgetOffset(e);
this.dragStop(posix);
}
if (this.isResizing) {
this.isResizing = false;
this.$player = null;
this.resizeStop();
}
});

 

到此整个的画布的功能结构已经实现,剩下的只需要抽象出获取鼠标位置信息,组件尺寸信息的函数和边界就可以实现一个简单的画布了。 
地址:https://github.com/song111/Draggleble.js
posted @ 2019-02-14 09:46  半夜盗贼  阅读(1293)  评论(0编辑  收藏  举报