<template>
|
<div ref="box">
|
<slot></slot>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
props: {
|
index: {
|
type: Number,
|
default: 0
|
},
|
w: {
|
type: Number,
|
default: 100
|
},
|
h: {
|
type: Number,
|
default: 100
|
},
|
data: {
|
type: Object,
|
default: null
|
},
|
tags: {
|
type: Object,
|
default: null
|
},
|
toDOMId: {
|
type: String,
|
default: ''
|
}
|
},
|
data() {
|
return {
|
grabEvents: ['mousedown', 'touchstart'],
|
moveEvents: ['mousemove', 'touchmove'],
|
releaseEvents: ['mouseup', 'touchend'],
|
isAdd: false,
|
isOnDowm: false,
|
boxContent: {},
|
beginx: 0,
|
beginy: 0,
|
item: '',
|
// 移动复制的Dom 节点
|
CloneDom: null
|
}
|
},
|
mounted() {
|
this.item = this.$refs.box
|
this.listenEvents()
|
},
|
methods: {
|
// 封装API
|
_addGrabListeners() {
|
this.grabEvents.forEach(e => {
|
window.addEventListener(e, this._onMouseDown, { passive: false })
|
})
|
this.moveEvents.forEach(e => {
|
window.document.addEventListener(e, this._onMouseMove, {
|
passive: false
|
})
|
})
|
this.releaseEvents.forEach(e => {
|
window.document.addEventListener(e, this._onMouseUp, { passive: false })
|
})
|
},
|
|
listenEvents() {
|
this._addGrabListeners()
|
},
|
|
_onMouseDown(e) {
|
this.boxContent = this._getContainerRect(this.item)
|
this.isAdd = this._current(this.boxContent, e)
|
if (!this.isOnDowm && this.isAdd) {
|
this.isOnDowm = true
|
// this.emit('isOnDowm', this.)
|
this.$emit('down', {
|
index: this.index,
|
data: this.data,
|
tags: this.tags
|
})
|
this.beginx = e.clientX || e.changedTouches[0].clientX
|
this.beginy = e.clientY || e.changedTouches[0].clientY
|
this.CloneDom = this.item.cloneNode(true)
|
document.getElementsByTagName('body')[0].append(this.CloneDom)
|
this.CloneDom.style.position = 'absolute'
|
this.CloneDom.style.width = this.w + 'px'
|
this.CloneDom.style.height = this.h + 'px'
|
this.CloneDom.style.top = this.beginy - 20 + 'px'
|
this.CloneDom.style.left = this.beginx - 20 + 'px'
|
this.CloneDom.style.opacity = 0.4
|
}
|
},
|
_onMouseMove(e) {
|
if (!this.isOnDowm) return
|
let boxContent = this._getContainerRect(this.item)
|
this.boxContent = boxContent
|
let clientX = e.clientX || e.changedTouches[0].clientX
|
let clientY = e.clientY || e.changedTouches[0].clientY
|
let eventX = clientX - this.beginx
|
let eventY = clientY - this.beginy
|
this.beginy = clientY
|
this.beginx = clientX
|
if (!this.isAdd || !this.CloneDom) return
|
let x = eventX + this.CloneDom.offsetLeft
|
let y = eventY + this.CloneDom.offsetTop
|
if (this.CloneDom) {
|
this.CloneDom.style.position = 'absolute'
|
this.CloneDom.style.top = y + 'px'
|
this.CloneDom.style.left = x + 'px'
|
}
|
},
|
_onMouseUp(e) {
|
this.CloneDom &&
|
document.getElementsByTagName('body')[0].removeChild(this.CloneDom)
|
this.CloneDom = null
|
if (this.isOnDowm && this.isAdd) {
|
let clientX = e.clientX || e.changedTouches[0].clientX
|
let clientY = e.clientY || e.changedTouches[0].clientY
|
this.isOnDowm = false
|
if (this.toDOMId !== '') {
|
let toDOM = document.getElementById(this.toDOMId)
|
// 拖放对象 元素位置信息
|
let toDOMContent = this._getContainerRect(toDOM)
|
if (
|
clientY >= toDOMContent.top &&
|
clientY <= toDOMContent.bottom &&
|
clientX >= toDOMContent.left &&
|
clientX <= toDOMContent.right
|
) {
|
clientX = clientX - toDOMContent.left
|
clientY = clientY - toDOMContent.top
|
} else {
|
return false
|
}
|
}
|
console.log(clientX, '_onMouseUp clientX')
|
this.$emit('_getContainerRect', {
|
x: clientX,
|
y: clientY,
|
index: this.index,
|
data: this.data,
|
tags: this.tags
|
})
|
|
// this.reset()
|
}
|
return false
|
},
|
// 判断鼠标是否在元素上
|
/**
|
* @function 判断鼠标是否在元素上
|
* @param { object } 元素的位置信息 left right top bottom width height
|
* @param { object } event事件信息
|
* @returns { boolean } true 是 false 否
|
*/
|
_current(getContainerRect, e) {
|
if (
|
getContainerRect.left <= (e.clientX || e.changedTouches[0].clientX) &&
|
getContainerRect.right >= (e.clientX || e.changedTouches[0].clientX) &&
|
getContainerRect.top <= (e.clientY || e.changedTouches[0].clientY) &&
|
getContainerRect.bottom >= (e.clientY || e.changedTouches[0].clientY)
|
) {
|
return true
|
} else {
|
return false
|
}
|
},
|
/**
|
* @function 获取元素位置信息
|
* @param { string } DOM元素
|
* @returns { object } left right top bottom width height
|
*/
|
_getContainerRect(element) {
|
// console.log(element, 'element')
|
const _rect = element.getBoundingClientRect()
|
return {
|
left: _rect.left,
|
right: _rect.right,
|
top: _rect.top,
|
bottom: _rect.bottom,
|
width: _rect.width,
|
height: _rect.height
|
}
|
},
|
/**
|
* 还原位置信息
|
*/
|
reset() {
|
if (this.item.style.position) {
|
this.item.style.position = 'static'
|
}
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
img {
|
width: 100%;
|
height: 100%;
|
}
|
</style>
|