基于jQuery3.0.0开发的8个方向拉伸缩放插件,兼容transform:scale(0.1)缩放后自适应
项目中需要实现拉伸div的功能,顺便封装成一个插件,废话少说,直接上代码
/*
* Created By KentKun
* Created On 2020/08/28
* 元素8个方向重新调整大小
* 基于JQuery开发
*/
;
(function(global) {
let _this = null;
function resizeDom(option) {
this._init(option);
//鼠标按下位置
this.mouseStart = {};
//拖动的节点
this.moveDom = null;
//拖动之前保存宽高,xy
this.baseWidth = 0;
this.baseHeight = 0;
this.baseLeft = 0;
this.baseTop = 0;
//拖动时宽高,XY
this.dragWidth = 0;
this.dragHeight = 0;
this.dragLeft = 0;
this.dragTop = 0;
//当前正在移动的事件名称
this.nowDrag = '';
}
resizeDom.prototype = {
//初始化
_init(option) {
let defaultConfig = {
//拖动节点的id
id: null,
//父级容器id(边界)
parentId: null,
//不允许超出父级容器
noBeyondParent: true,
//是否检查父级容器缩放系数
checkScale: true,
//图层
zIndex: 6,
//最小宽高度
minW: 50,
minH: 50,
//拖动模块的大小
dragSize: 10,
//缩放倍数
zoomNum: 1,
//8个方向
directionArr: ['left', 'top', 'right', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'],
//拖拽成功回调函数,返回 l,t,w,h
dragCallBack: null
}
this.config = this._extend(defaultConfig, option, true);
this.$dom = $('#' + this.config.id);
this.$pDom = $('#' + this.config.parentId);
//给元素添加8个可拖动的节点
if (this.config.directionArr.indexOf('left') > -1) {
this._addToLeft();
}
if (this.config.directionArr.indexOf('top') > -1) {
this._addToTop();
}
if (this.config.directionArr.indexOf('right') > -1) {
this._addToRight();
}
if (this.config.directionArr.indexOf('bottom') > -1) {
this._addToBottom();
}
if (this.config.directionArr.indexOf('topLeft') > -1) {
this._addToTopLeft();
}
if (this.config.directionArr.indexOf('topRight') > -1) {
this._addToTopRight();
}
if (this.config.directionArr.indexOf('bottomLeft') > -1) {
this._addToBottomLeft();
}
if (this.config.directionArr.indexOf('bottomRight') > -1) {
this._addToBottomRight();
}
},
//合并配置项
_extend(o, n, override) {
for (let key in n) {
if (n.hasOwnProperty(key) && (!o.hasOwnProperty(key) || override)) {
o[key] = n[key];
}
}
return o;
},
//设置缩放倍数
_setZoom(zoom) {
this.config.zoomNum = zoom;
},
//根据父级transform的scale更新zoomNum
_updateZoomByPdom() {
let transform = this.$pDom.css('transform') ||
this.$pDom.css('-webkit-transform') ||
this.$pDom.css('-moz-transform') ||
this.$pDom.css('-ms-transform') ||
this.$pDom.css('-o-transform')
if (transform != 'none') {
let scaleNum = Number(transform.replace(/[^0-9\-,.]/g, '').split(',')[0]);
if (scaleNum != NaN) {
this._setZoom(scaleNum);
}
}
},
//向左拖动
_addToLeft() {
let ele = $('<div>'),
that = this;
ele.css({
width: this.config.dragSize + 'px',
height: 'calc(100% - ' + this.config.dragSize + 'px)',
position: 'absolute',
'z-index': this.config.zIndex,
left: '-' + (this.config.dragSize / 2) + 'px',
top: (this.config.dragSize / 2) + 'px',
cursor: 'w-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragLeft');
}
})
},
//向上拖动
_addToTop() {
let ele = $('<div>'),
that = this;
ele.css({
width: 'calc(100% - ' + this.config.dragSize + 'px)',
height: this.config.dragSize + 'px',
position: 'absolute',
'z-index': this.config.zIndex,
left: (this.config.dragSize / 2) + 'px',
top: '-' + (this.config.dragSize / 2) + 'px',
cursor: 'n-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragTop');
}
})
},
//向右拖动
_addToRight() {
let ele = $('<div>'),
that = this;
ele.css({
width: this.config.dragSize + 'px',
height: 'calc(100% - ' + this.config.dragSize + 'px)',
position: 'absolute',
'z-index': this.config.zIndex,
right: '-' + (this.config.dragSize / 2) + 'px',
top: (this.config.dragSize / 2) + 'px',
cursor: 'e-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragRight');
}
})
},
//向下拖动
_addToBottom() {
let ele = $('<div>'),
that = this;
ele.css({
width: 'calc(100% - ' + this.config.dragSize + 'px)',
height: this.config.dragSize + 'px',
position: 'absolute',
'z-index': this.config.zIndex,
left: (this.config.dragSize / 2) + 'px',
bottom: '-' + (this.config.dragSize / 2) + 'px',
cursor: 's-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragBottom');
}
})
},
//向左上拖动
_addToTopLeft() {
let ele = $('<div>'),
that = this;
ele.css({
width: this.config.dragSize + 'px',
height: this.config.dragSize + 'px',
position: 'absolute',
'z-index': this.config.zIndex,
left: '-' + (this.config.dragSize / 2) + 'px',
top: '-' + (this.config.dragSize / 2) + 'px',
cursor: 'nw-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragTopLeft');
}
})
},
//向右上拖动
_addToTopRight() {
let ele = $('<div>'),
that = this;
ele.css({
width: this.config.dragSize + 'px',
height: this.config.dragSize + 'px',
position: 'absolute',
'z-index': this.config.zIndex,
right: '-' + (this.config.dragSize / 2) + 'px',
top: '-' + (this.config.dragSize / 2) + 'px',
cursor: 'ne-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragTopRight');
}
})
},
//向左下拖动
_addToBottomLeft() {
let ele = $('<div>'),
that = this;
ele.css({
width: this.config.dragSize + 'px',
height: this.config.dragSize + 'px',
position: 'absolute',
'z-index': this.config.zIndex,
left: '-' + (this.config.dragSize / 2) + 'px',
bottom: '-' + (this.config.dragSize / 2) + 'px',
cursor: 'sw-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragBottomLeft');
}
})
},
//向右下拖动
_addToBottomRight() {
let ele = $('<div>'),
that = this;
ele.css({
width: this.config.dragSize + 'px',
height: this.config.dragSize + 'px',
position: 'absolute',
'z-index': this.config.zIndex,
right: '-' + (this.config.dragSize / 2) + 'px',
bottom: '-' + (this.config.dragSize / 2) + 'px',
cursor: 'se-resize',
overflow: 'hidden',
opacity: 0
})
this.$dom.append(ele);
ele.mousedown(function(e) {
e = e || window.event;
//左键按下才处理
if (e.button == 0) {
_this = that;
_this.moveDom = ele;
_this._domMouseDown(e, '_doDragBottomRight');
}
})
},
//鼠标位置按下
_domMouseDown(e, doDrag) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
//更新缩放系数
if (_this.config.checkScale)
_this._updateZoomByPdom();
_this.mouseStart.x = e.pageX;
_this.mouseStart.y = e.pageY;
//拖动时的whlt
_this.dragLeft = _this.$dom[0].offsetLeft;
_this.dragTop = _this.$dom[0].offsetTop;
_this.dragWidth = _this.$dom[0].offsetWidth;
_this.dragHeight = _this.$dom[0].offsetHeight;
//保存开始的whlt
_this.baseLeft = _this.dragLeft;
_this.baseTop = _this.dragTop;
_this.baseWidth = _this.dragWidth;
_this.baseHeight = _this.dragHeight;
//保存当前移动的事件名称
_this.nowDrag = doDrag;
if (_this.setCapture) {
_this.onmousemove = doDrag;
_this.onmouseup = stopDrag;
_this.setCapture();
} else {
document.addEventListener('mousemove', _this[doDrag], true);
document.addEventListener('mouseup', _this._stopDragAll, true);
}
},
//往左移动
_doDragLeft(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveX = (e.pageX - _this.mouseStart.x) / (_this.config.zoomNum * 10) * 10, //移动的距离
w = _this.baseWidth - moveX,
l = _this.baseLeft + moveX;
if (w < _this.config.minW) {
w = _this.config.minW;
l = _this.baseWidth + _this.baseLeft - _this.config.minW;
}
if (_this.config.noBeyondParent && l < 0) {
l = 0;
w = _this.baseWidth + _this.baseLeft;
}
_this.$dom.css({
width: w + 'px',
left: l + 'px'
})
_this.dragWidth = w;
_this.dragLeft = l;
},
//往上移动
_doDragTop(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveY = (e.pageY - _this.mouseStart.y) / (_this.config.zoomNum * 10) * 10, //移动的距离
h = _this.baseHeight - moveY,
t = moveY + _this.baseTop;
if (h < _this.config.minH) {
h = _this.config.minH;
t = _this.baseHeight + _this.baseTop - _this.config.minH;
}
if (_this.config.noBeyondParent && t < 0) {
t = 0;
h = _this.baseHeight + _this.baseTop;
}
_this.$dom.css({
height: h + 'px',
top: t + 'px'
})
_this.dragHeight = h;
_this.dragTop = t;
},
//往右移动
_doDragRight(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveX = (e.pageX - _this.mouseStart.x) / (_this.config.zoomNum * 10) * 10, //移动的距离
w = moveX + _this.baseWidth;
if (w < _this.config.minW) {
w = _this.config.minW;
}
if (_this.config.noBeyondParent && (w >= _this.$pDom[0].offsetWidth - _this.baseLeft)) {
w = _this.$pDom[0].offsetWidth - _this.baseLeft;
}
_this.$dom.css({
width: w + 'px',
})
_this.dragWidth = w;
},
//往下移动
_doDragBottom(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveY = (e.pageY - _this.mouseStart.y) / (_this.config.zoomNum * 10) * 10, //移动的距离
h = moveY + _this.baseHeight;
if (h < _this.config.minH) {
h = _this.config.minH;
}
if (_this.config.noBeyondParent && (h >= _this.$pDom[0].offsetHeight - _this.baseTop)) {
h = _this.$pDom[0].offsetHeight - _this.baseTop;
}
_this.$dom.css({
height: h + 'px'
})
_this.dragHeight = h;
},
//往左上移动
_doDragTopLeft(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveX = (e.pageX - _this.mouseStart.x) / (_this.config.zoomNum * 10) * 10,
moveY = (e.pageY - _this.mouseStart.y) / (_this.config.zoomNum * 10) * 10,
w = _this.baseWidth - moveX,
h = _this.baseHeight - moveY,
l = _this.baseLeft + moveX,
t = _this.baseTop + moveY;
if (w < _this.config.minW) {
w = _this.config.minW;
l = _this.baseWidth + _this.baseLeft - _this.config.minW;
}
if (h < _this.config.minH) {
h = _this.config.minH;
t = _this.baseHeight + _this.baseTop - _this.config.minH;
}
if (_this.config.noBeyondParent && l < 0) {
l = 0;
w = _this.baseWidth + _this.baseLeft;
}
if (_this.config.noBeyondParent && t < 0) {
t = 0;
h = _this.baseHeight + _this.baseTop;
}
_this.$dom.css({
width: w + 'px',
height: h + 'px',
left: l + 'px',
top: t + 'px'
})
_this.dragWidth = w;
_this.dragHeight = h;
_this.dragLeft = l;
_this.dragTop = t;
},
//往右上移动
_doDragTopRight(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveX = (e.pageX - _this.mouseStart.x) / (_this.config.zoomNum * 10) * 10,
moveY = (e.pageY - _this.mouseStart.y) / (_this.config.zoomNum * 10) * 10,
w = _this.baseWidth + moveX,
h = _this.baseHeight - moveY,
t = _this.baseTop + moveY;
if (w < _this.config.minW) {
w = _this.config.minW;
}
if (h < _this.config.minH) {
h = _this.config.minH;
t = _this.baseHeight + _this.baseTop - _this.config.minH;
}
if (_this.config.noBeyondParent && (w >= _this.$pDom[0].offsetWidth - _this.baseLeft)) {
w = _this.$pDom[0].offsetWidth - _this.baseLeft;
}
if (_this.config.noBeyondParent && t < 0) {
t = 0;
h = _this.baseHeight + _this.baseTop;
}
_this.$dom.css({
width: w + 'px',
height: h + 'px',
top: t + 'px'
})
_this.dragWidth = w;
_this.dragHeight = h;
_this.dragTop = t;
},
//往左下移动
_doDragBottomLeft(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveX = (e.pageX - _this.mouseStart.x) / (_this.config.zoomNum * 10) * 10,
moveY = (e.pageY - _this.mouseStart.y) / (_this.config.zoomNum * 10) * 10,
w = _this.baseWidth - moveX,
h = _this.baseHeight + moveY,
l = _this.baseLeft + moveX;
if (w < _this.config.minW) {
w = _this.config.minW;
l = _this.baseWidth + _this.baseLeft - _this.config.minW;
}
if (h < _this.config.minH) {
h = _this.config.minH;
}
if (_this.config.noBeyondParent && l < 0) {
l = 0;
w = _this.baseWidth + _this.baseLeft;
}
if (_this.config.noBeyondParent && (h >= _this.$pDom[0].offsetHeight - _this.baseTop)) {
h = _this.$pDom[0].offsetHeight - _this.baseTop;
}
_this.$dom.css({
width: w + 'px',
height: h + 'px',
left: l + 'px'
})
_this.dragWidth = w;
_this.dragHeight = h;
_this.dragLeft = l;
},
//往右下移动
_doDragBottomRight(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
let moveX = (e.pageX - _this.mouseStart.x) / (_this.config.zoomNum * 10) * 10,
moveY = (e.pageY - _this.mouseStart.y) / (_this.config.zoomNum * 10) * 10,
w = moveX + _this.baseWidth,
h = moveY + _this.baseHeight;
if (w < _this.config.minW) {
w = _this.config.minW;
}
if (h < _this.config.minH) {
h = _this.config.minH;
}
if (_this.config.noBeyondParent && (w >= _this.$pDom[0].offsetWidth - _this.baseLeft)) {
w = _this.$pDom[0].offsetWidth - _this.baseLeft;
}
if (_this.config.noBeyondParent && (h >= _this.$pDom[0].offsetHeight - _this.baseTop)) {
h = _this.$pDom[0].offsetHeight - _this.baseTop;
}
_this.$dom.css({
width: w + 'px',
height: h + 'px'
})
_this.dragWidth = w;
_this.dragHeight = h;
},
//停止往各个方向移动
_stopDragAll(e) {
e = e || window.event;
e.stopPropagation();
e.preventDefault();
if (_this.moveDom.releaseCapture) {
_this.moveDom.onmousemove = null;
_this.moveDom.onmouseup = null;
_this.moveDom.releaseCapture();
} else {
document.removeEventListener('mousemove', _this[_this.nowDrag], true);
document.removeEventListener('mouseup', _this._stopDragAll, true);
}
//成功回调
if (_this.config.dragCallBack != null) {
let data = {
left: _this.dragLeft,
top: _this.dragTop,
width: _this.dragWidth,
height: _this.dragHeight
}
_this.config.dragCallBack(data);
}
}
}
//全局挂载resizeDom
global.resizeDom = resizeDom;
})(this)
使用方法也很简单,直接创建resizeDom对象,接收一个option对象,需传入需要伸缩的节点的id,以及所在父级的id,父容器的作用是防止拖出边界,当然也可以设置noBeyondParent为false来允许超出,利用dragCallBack来接收一个缩放结果data,这里的data是一个对象,含有4个属性,left、top、width、height; 其他参数可选择性传入
let resize = new resizeDom({
id: 'id',
parentId: 'parentId',
//成功回调
dragCallBack: data => {
console.log(data)
}
})
里面的相关参数可选择性传入
let defaultConfig = {
//拖动节点的id
id: null,
//父级容器id(边界)
parentId: null,
//不允许超出父级容器
noBeyondParent: true,
//是否检查父级容器缩放系数
checkScale: true,
//图层
zIndex: 6,
//最小宽高度
minW: 50,
minH: 50,
//拖动模块的大小
dragSize: 10,
//缩放倍数
zoomNum: 1,
//8个方向
directionArr: ['left', 'top', 'right', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'],
//拖拽成功回调函数,返回 l,t,w,h
dragCallBack: null
}