function drag (el, binding, vnode) {
el.onmousedown = function (event) {
const x = event.pageX - el.offsetLeft
const y = event.pageY - el.offsetTop
const dragDomWidth = el.offsetWidth
const dragDomHeight = el.offsetHeight
const screenWidth = document.body.scrollWidth
const screenHeight = binding.value || document.body.clientHeight
const minDragDomLeft = 0
const maxDragDomLeft = screenWidth - dragDomWidth
const minDragDomTop = 0
const maxDragDomTop = screenHeight - dragDomHeight
document.onmousemove = function (event) {
let top = event.pageY - y
let left = event.pageX - x
if (top < minDragDomTop) {
top = minDragDomTop
} else if (top > maxDragDomTop) {
top = maxDragDomTop
}
if (left < minDragDomLeft) {
left = minDragDomLeft
} else if (left > maxDragDomLeft) {
left = maxDragDomLeft
}
el.style.left = left + 'px'
el.style.top = top + 'px'
vnode.context.$emit('move', {
top,
left
})
}
document.onmouseup = function () {
vnode.context.$emit('drag-end', {
top: el.style.top,
left: el.style.left
})
document.onmousemove = null
document.onmouseup = null
}
}
}
export default {
bind: drag
}
组件
<template>
<div
v-drag="1080"
class="points-area-wrap"
:class="{ animation }"
:style="pointStyle">
<span
v-if="$slots.default"
class="point-title"
@click="handleClick"><slot /></span>
<span
class="pin"
@click="handleClick">
<i class="iconfont icon-ios-pin" />
</span>
</div>
</template>
<script>
import drag from '@/directive/drag'
export default {
name: 'PointsQuYu',
directives: {
drag
},
props: {
animation: {
type: Boolean,
default: false
},
top: {
type: String,
default: null
},
left: {
type: String,
default: null
},
right: {
type: String,
default: null
},
bottom: {
type: String,
default: null
}
},
data () {
return {
dragged: false
}
},
computed: {
pointStyle () {
return {
top: this.top || 0,
left: this.left || 0
}
}
},
created () {
this.$on('move', () => {
this.dragged = true
})
},
methods: {
handleClick () {
alert('quyu')
if (!this.dragged) {
this.$emit('click')
} else {
this.dragged = false
}
}
}
}
</script>
<style scoped lang="stylus">
@keyframes bounce {
25% {
transform: translateY(10px);
}
50%, 100% {
transform: translateY(0);
}
75% {
transform: translateY(-10px);
}
}
.points-area-wrap {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1;
.point-title {
width: auto;
height: 25px;
line-height: 25px;
font-size: 15px;
background-color: rgba(22, 65, 255, 0.8);
border-radius: 24px;
color: #fff;
padding: 0 10px;
cursor: pointer;
}
.pin {
margin-top: 12px;
width: 30px;
height: 30px;
cursor: pointer;
.iconfont {
color: #1890ff;
font-size: 30px;
}
}
&.animation {
animation: bounce 1s linear infinite;
}
}
</style>
网友评论