-
-
-
- )
- }
- }).$mount(div)
- this.$nextTick(() => {
- this.vnode = vnode
- this.domNode = div
- })
- },
- methods: {
+
+ )
+ }
+ }).$mount(div)
+ this.$nextTick(() => {
+ this.vnode = vnode
+ callback()
+ })
+ },
onPopupAlign: (placement, domNode, target, align) => {
if (!placement) {
- return;
+ return
}
// 根据当前坐标设置动画点
const rect = domNode.getBoundingClientRect()
const transformOrigin = {
top: '50%',
left: '50%',
- };
+ }
if (placement.indexOf('top') >= 0 || placement.indexOf('Bottom') >= 0) {
- transformOrigin.top = `${rect.height - align.offset[1]}px`;
+ transformOrigin.top = `${rect.height - align.offset[1]}px`
} else if (placement.indexOf('Top') >= 0 || placement.indexOf('bottom') >= 0) {
- transformOrigin.top = `${-align.offset[1]}px`;
+ transformOrigin.top = `${-align.offset[1]}px`
}
if (placement.indexOf('left') >= 0 || placement.indexOf('Right') >= 0) {
- transformOrigin.left = `${rect.width - align.offset[0]}px`;
+ transformOrigin.left = `${rect.width - align.offset[0]}px`
} else if (placement.indexOf('right') >= 0 || placement.indexOf('Left') >= 0) {
- transformOrigin.left = `${-align.offset[0]}px`;
+ transformOrigin.left = `${-align.offset[0]}px`
}
- target.style.transformOrigin = `${transformOrigin.left} ${transformOrigin.top}`;
+ target.style.transformOrigin = `${transformOrigin.left} ${transformOrigin.top}`
},
addEventHandle(old, fn) {
if (!old) {
@@ -111,68 +146,107 @@ export default {
return old === fn ? old : [old, fn]
}
},
- computeOffset(popup, text, placement) {
+ computeOffset(popup, text, placement, scale) {
let { width, height, top, left } = text
// you cant change the properties of DOMRect
top += window.scrollY
left += window.scrollX
+ // FIXME: we can get the numbers from scale, but that's not what we really want
+ const p = { width: popup.width / scale, height: popup.height / scale }
const ret = { left, top }
- if (/top/.test(placement)) ret.top -= popup.height
+ if (/top/.test(placement)) ret.top -= p.height
if (/bottom/.test(placement)) ret.top += height
- if (/left/.test(placement)) ret.left -= popup.width
+ if (/left/.test(placement)) ret.left -= p.width
if (/right/.test(placement)) ret.left += width
+ // FIXME: magic number 20 & 14 comes from the offset of triangle
if (/Left/.test(placement)) {
+ if (this.arrowPointAtCenter) ret.left += width / 2 - 20
} else if(/Right/.test(placement)) {
- ret.left += (width - popup.width)
+ ret.left += (width - p.width)
+ if (this.arrowPointAtCenter) ret.left -= width / 2 - 20
} else if(/(top)|(bottom)/.test(placement)) {
- ret.left += (width - popup.width) / 2
+ ret.left += (width - p.width) / 2
}
if (/Top/.test(placement)) {
+ if (this.arrowPointAtCenter) ret.top += height / 2 - 14
} else if(/Bottom/.test(placement)) {
- ret.top += (height - popup.height)
+ ret.top += (height - p.height)
+ if (this.arrowPointAtCenter) ret.top -= height / 2 - 14
} else if(/(left)|(right)/.test(placement)) {
- ret.top += (height - popup.height) / 2
+ ret.top += (height - p.height) / 2
}
return ret
},
showNode() {
- this.visible = true
- this.$nextTick(() => {
- const popup = this.vnode.$el.getBoundingClientRect()
- const content = this.$el.getBoundingClientRect()
- const { left, top } = this.computeOffset(popup, content, this.placement)
- this.vnode.left = left
- this.vnode.top = top
+ this.mountNode(() => {
+ this.visible = true
+ this.$nextTick(() => {
+ const popup = this.vnode.$el.getBoundingClientRect()
+ const [, scale = 1] = window.getComputedStyle(this.vnode.$el).transform.match(/matrix\((.*?),/) || []
+ const content = this.$el.getBoundingClientRect()
+ const place = this.autoAdjustOverflow ? this.checkPosition(popup, content, this.placement, scale) : this.placement
+ this.realPlacement = place
+ const { left, top } = this.computeOffset(popup, content, place, scale)
+ this.vnode.left = left
+ this.vnode.top = top
+ })
+ this.onPopupAlign(this.realPlacement, this.$el, this.vnode.$el, { offset: [0,0] })
})
- this.onPopupAlign(this.placement, this.$el, this.vnode.$el, { offset: [0,0] })
},
- hideNode() {
+ hideNode(e) {
+ if (!this.vnode) return
+ if (e.relatedTarget === this.vnode.$el) {
+ return
+ }
this.visible = false
+ },
+ checkShow(e) {
+ if (this.t2) {
+ clearTimeout(this.t2)
+ this.t2 = null
+ }
+ if (this.mouseEnterDelay) {
+ this.t1 = window.setTimeout(() => {
+ this.showNode(e)
+ }, +this.mouseEnterDelay * 1e3)
+ }
+ },
+ checkHide(e) {
+ if (this.t1) {
+ clearTimeout(this.t1)
+ this.t1 = null
+ }
+ if (this.mouseLeaveDelay) {
+ this.t2 = window.setTimeout(() => {
+ this.hideNode(e)
+ }, +this.mouseLeaveDelay * 1e3)
+ }
}
},
render(h) {
- let node = this.vnode
const inner = this.$slots.default[0]
inner.data = inner.data || {}
inner.data.on = inner.data.on || {}
- inner.data.on.mouseenter = this.addEventHandle(inner.data.on.mouseenter, this.showNode)
- inner.data.on.mouseleave = this.addEventHandle(inner.data.on.mouseleave, this.hideNode)
-// console.info(inner)
+ inner.data.on.mouseenter = this.addEventHandle(inner.data.on.mouseenter, this.checkShow)
+ inner.data.on.mouseleave = this.addEventHandle(inner.data.on.mouseleave, this.checkHide)
+
return this.$slots.default[0]
},
updated() {
+ if (!this.vnode) return
const popup = this.vnode.$el.getBoundingClientRect()
+ const [, scale = 1] = window.getComputedStyle(this.vnode.$el).transform.match(/matrix\((.*?),/) || []
const content = this.$el.getBoundingClientRect()
- const { left, top } = this.computeOffset(popup, content, this.placement)
+ const { left, top } = this.computeOffset(popup, content, this.realPlacement, scale)
this.vnode.left = left
this.vnode.top = top
},
- beforeDestory() {
- console.info('没有成功清除实例 ,看vue panel')
- this.vnode.$destroy();
- this.domNode && this.domNode.remove()
+ beforeDestroy() {
+ if (!this.vnode) return
+ this.vnode.$el.remove()
+ this.vnode.$destroy()
}
}
diff --git a/examples/tooltip.vue b/examples/tooltip.vue
deleted file mode 100644
index 651957dbd..000000000
--- a/examples/tooltip.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
- This is just a test, put your cursor here
-
-
-
-
-