/**
* 在被拖拽元素销毁前
* 1、将下列数据清空
* sessionStorage.setItem(元素id + "css-right","");
* sessionStorage.setItem(元素id + "css-top","");
* sessionStorage.setItem(元素id + "distX","");
* sessionStorage.setItem(元素id + "distY","");
*2、若页面中还有其他拖动元素 将其传入
* dragMatrix(document.getElementById(xxx))
*/
/* 定义距离尺寸的存储池 */
let E_SIZER = {}
/* 定义元素变量 */
let ELEMENT = null
/**定义元素距离上、右、下、左可移动的最大距离 */
let [mt, mr, mb, ml] = [0, 0, 0, 0];
//元素translate x与y的值
let [moveX, moveY] = [0, 0];
/**
* 获取元素计算后的样式
* @param {Element} el 目标节点
* @param {String} attr 目标样式规则
* @returns {string}
**/
function getStyle(
el,
attr
) {
if (typeof window.getComputedStyle !== 'undefined') {
return window.getComputedStyle(el, null)[attr]
} else if (typeof el.currentStyle !== 'undefiend') {
return el.currentStyle[attr]
}
return ''
}
/**
* 绑定事件
* @param {MouseEvent} evte 鼠标事件对象
* @returns {undefined}
**/
function initBindEvent(el) {
ELEMENT = el
// 绑定mousedown事件
ELEMENT.addEventListener('mousedown', bindMouseDownEvent, false)
// 绑定mouseup事件
document.addEventListener('mouseup', bindMouseUpEvent, false)
}
/**
* mousedown事件
* @param {MouseEvent} evte 鼠标事件对象
* @returns {undefined}
**/
function bindMouseDownEvent(
evte
) {
evte.stopPropagation()
evte.preventDefault()
let oldDistX = sessionStorage.getItem($(ELEMENT).attr('id') + 'distX') || "",
oldDistY = sessionStorage.getItem($(ELEMENT).attr('id') + 'distY') || "";
if (!oldDistX.length && oldDistY.length) {
// 解析matrix的正则
let matrix3dReg1 = /^matrix3d\((?:[-\d.]+,\s*){12}([-\d.]+),\s*([-\d.]+)(?:,\s*[-\d.]+){2}\)/,
matrixReg = /^matrix\((?:[-\d.]+,\s*){4}([-\d.]+),\s*([-\d.]+)\)$/
// 获取解析后的transform样式属性值
let matrix3dSourceValue = getStyle(
evte.target,
'transform'
)
let matrix3dArrValue = matrix3dSourceValue.match(matrix3dReg1) || matrix3dSourceValue.match(matrixReg)
// 记录鼠标点击时的坐标
E_SIZER['clientX'] = evte.clientX
E_SIZER['clientY'] = evte.clientY
// 记录matrix解析后的translateX & translateY的值
E_SIZER['targetX'] = matrix3dArrValue[1]
E_SIZER['targetY'] = matrix3dArrValue[2]
// 计算坐标边界巨离
E_SIZER['distX'] = E_SIZER['clientX'] - E_SIZER['targetX']
E_SIZER['distY'] = E_SIZER['clientY'] - E_SIZER['targetY']
} else {
// 计算坐标边界巨离
E_SIZER['distX'] = oldDistX;
E_SIZER['distY'] = oldDistY;
}
// 绑定mousemove事件
document.addEventListener('mousemove', bindMouseMoveEvent, false)
}
/**
* mousemove事件
* @param {MouseEvent} evte 鼠标事件对象
* @returns {undefined}
**/
function bindMouseMoveEvent(
evte
) {
evte.stopPropagation()
evte.preventDefault()
let moveX = evte.clientX - E_SIZER['distX']
let moveY = evte.clientY - E_SIZER['distY']
//当被拖动元素大小发生变化时需重新计算可移动的最大距离
let isInitBoundary = sessionStorage.getItem("initBoundary");
if (isInitBoundary == 'true') {
initBoundary(ELEMENT);
sessionStorage.setItem("initBoundary", "");
}
//当移动元素大于边界值时处理
if (moveX < ml) {
moveX = ml;
} else if (moveX > mr) {
moveX = mr;
}
if (moveY < mt) {
moveY = mt;
} else if (moveY > mb) {
moveY = mb;
}
sessionStorage.setItem($(ELEMENT).attr("id") + "distX", E_SIZER['distX']);
sessionStorage.setItem($(ELEMENT).attr("id") + "distY", E_SIZER['distY']);
// 写入style
ELEMENT.style.transform =
ELEMENT.style.mozTransform =
ELEMENT.style.webkitTransform =
`translate3d(${moveX}px, ${moveY}px, 1px)`
}
/**
* mouseup事件
* @param {MouseEvent} evte 鼠标事件对象
* @returns {undefined}
**/
function bindMouseUpEvent(
evte
) {
evte.stopPropagation()
evte.preventDefault()
if ($(evte.target).attr("id") != $(ELEMENT).attr('id') || $(evte.target).parents().attr('id') != $(ELEMENT).attr("id")) {
document.removeEventListener('mousemove', bindMouseMoveEvent)
return;
}
//元素停止拖动重新确定元素的位置
let right = 0;
if (moveX < 0) {
right = document.documentElement.clientWidth - (moveX - ml) - $(ELEMENT).width();
if (right > document.documentElement.clientWidth - $(ELEMENT).width()) {
right = document.documentElement.clientWidth - $(ELEMENT).width();
}
} else {
right = mr - moveX;
if (right < 0) {
right = 0;
}
}
sessionStorage.setItem($(ELEMENT).attr("id") + "css-right", JSON.stringify(right));
$(ELEMENT).css("right", right);
let top = 0;
if (moveY < 0) {
top = moveY - mt;
if (top < 0) {
top = 0;
}
} else {
top = document.documentElement.clientHeight - (mb - moveY) - $(ELEMENT).height();
if (top > document.documentElement.clientHeight - $(ELEMENT).height()) {
top = document.documentElement.clientHeight - $(ELEMENT).height();
}
}
sessionStorage.setItem($(ELEMENT).attr("id") + "css-top", JSON.stringify(top));
$(ELEMENT).css("top", top);
initBoundary(ELEMENT);
document.removeEventListener('mousemove', bindMouseMoveEvent)
}
/**
*
* 初始化边界
*/
function initBoundary(el) {
if ($(el).attr("id") == $(ELEMENT).attr("id")) {
let s_right = sessionStorage.getItem($(el).attr("id") + "css-right"),
s_top = sessionStorage.getItem($(el).attr("id") + "css-top");
if (s_right) {
s_right = JSON.parse(s_right);
$(el).css("right", s_right);
}
if (s_top) {
s_right = JSON.parse(s_top);
$(el).css("top", s_top);
}
}
let top = $(el).css("top").substring(0, $(el).css("top").length - 2) - 0;
sessionStorage.setItem($(dom).attr("id" + "css-top"), JSON.stringify(top));
let right = $(el).css("right").substring(0, $(el).css("right").length - 2) - 0;
sessionStorage.setItem($(dom).attr("id" + "css-right"), JSON.stringify(right));
let width = $(el).width(),
height = $(el).height();
ml = -(document.documentElement.clientWidth - right - width);
mr = right;
mt = -top;
mb = document.documentElement.clientHeight - top - height;
}
export default function dragMatrix(el) {
sessionStorage.setItem($(el).attr("id") + "css-right", "");
sessionStorage.setItem($(el).attr("id") + "css-top", "");
initBoundary(el);
// 执行初始化方法
initBindEvent(el)
}
拖拽元素需要有的样式