Skip to content

Commit 0bef1fe

Browse files
authored
Merge pull request #124 from wwayne/update-position-check
Consider both vertical and horizontal into place re-calculation
2 parents 3f61ea5 + bcff5d4 commit 0bef1fe

File tree

3 files changed

+276
-53
lines changed

3 files changed

+276
-53
lines changed

src/utils/getPosition.js

Lines changed: 128 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,54 +21,116 @@ export default function (e, target, node, place, effect, offset) {
2121
const defaultOffset = getDefaultPosition(effect, target.clientWidth, target.clientHeight, tipWidth, tipHeight)
2222
const {extraOffset_X, extraOffset_Y} = calculateOffset(offset)
2323

24-
const widnowWidth = window.innerWidth
24+
const windowWidth = window.innerWidth
2525
const windowHeight = window.innerHeight
2626

2727
// Get the edge offset of the tooltip
2828
const getTipOffsetLeft = (place) => {
29-
const offset_X = defaultOffset[place].x
29+
const offset_X = defaultOffset[place].l
30+
return mouseX + offset_X + extraOffset_X
31+
}
32+
const getTipOffsetRight = (place) => {
33+
const offset_X = defaultOffset[place].r
3034
return mouseX + offset_X + extraOffset_X
3135
}
3236
const getTipOffsetTop = (place) => {
33-
const offset_Y = defaultOffset[place].y
37+
const offset_Y = defaultOffset[place].t
38+
return mouseY + offset_Y + extraOffset_Y
39+
}
40+
const getTipOffsetBottom = (place) => {
41+
const offset_Y = defaultOffset[place].b
3442
return mouseY + offset_Y + extraOffset_Y
3543
}
3644

3745
// Judge if the tooltip has over the window(screen)
46+
const outsideVertical = () => {
47+
// Check for horazontal tooltip, if their vertical out of screen
48+
let result = false
49+
let newPlace
50+
if (getTipOffsetTop('left') < 0 && getTipOffsetBottom('left') <= windowHeight) {
51+
result = true
52+
newPlace = 'bottom'
53+
} else if (getTipOffsetBottom('left') > windowHeight && getTipOffsetTop('left') >= 0) {
54+
result = true
55+
newPlace = 'top'
56+
}
57+
if (result && outsideHorizontal().result) result = false
58+
return {result, newPlace}
59+
}
3860
const outsideLeft = () => {
39-
// if switch to right will out of screen, return false because switch placement doesn't make sense
40-
return getTipOffsetLeft('left') < 0 && getTipOffsetLeft('right') <= widnowWidth
61+
// For horizontal tooltip, if vertical out of screen, change the vertical place
62+
let {result, newPlace} = outsideVertical()
63+
if (!result && getTipOffsetLeft('left') < 0 && getTipOffsetRight('right') <= windowWidth) {
64+
result = true
65+
newPlace = 'right'
66+
}
67+
return {result, newPlace}
4168
}
4269
const outsideRight = () => {
43-
return getTipOffsetLeft('right') > widnowWidth && getTipOffsetLeft('left') >= 0
70+
let {result, newPlace} = outsideVertical()
71+
if (!result && getTipOffsetRight('right') > windowWidth && getTipOffsetLeft('left') >= 0) {
72+
result = true
73+
newPlace = 'left'
74+
}
75+
return {result, newPlace}
76+
}
77+
78+
const outsideHorizontal = () => {
79+
let result = false
80+
let newPlace
81+
if (getTipOffsetLeft('top') < 0 && getTipOffsetRight('top') <= windowWidth) {
82+
result = true
83+
newPlace = 'right'
84+
} else if (getTipOffsetRight('top') > windowWidth && getTipOffsetLeft('top') >= 0) {
85+
result = true
86+
newPlace = 'left'
87+
}
88+
89+
if (result && outsideVertical().result) result = false
90+
return {result, newPlace}
4491
}
4592
const outsideTop = () => {
46-
return getTipOffsetTop('top') < 0 && getTipOffsetTop('bottom') + tipHeight <= windowHeight
93+
let {result, newPlace} = outsideHorizontal()
94+
if (!result && getTipOffsetTop('top') < 0 && getTipOffsetBottom('bottom') <= windowHeight) {
95+
result = true
96+
newPlace = 'bottom'
97+
}
98+
return {result, newPlace}
4799
}
48100
const outsideBottom = () => {
49-
return getTipOffsetTop('bottom') + tipHeight > windowHeight && getTipOffsetTop('top') >= 0
101+
let {result, newPlace} = outsideHorizontal()
102+
if (!result && getTipOffsetBottom('bottom') > windowHeight && getTipOffsetTop('top') >= 0) {
103+
result = true
104+
newPlace = 'top'
105+
}
106+
return {result, newPlace}
50107
}
51108

52109
// Return new state to change the placement to the reverse if possible
53-
if (place === 'left' && outsideLeft()) {
110+
const outsideLeftResult = outsideLeft()
111+
const outsideRightResult = outsideRight()
112+
const outsideTopResult = outsideTop()
113+
const outsideBottomResult = outsideBottom()
114+
115+
if (place === 'left' && outsideLeftResult.result) {
54116
return {
55117
isNewState: true,
56-
newState: {place: 'right'}
118+
newState: {place: outsideLeftResult.newPlace}
57119
}
58-
} else if (place === 'right' && outsideRight()) {
120+
} else if (place === 'right' && outsideRightResult.result) {
59121
return {
60122
isNewState: true,
61-
newState: {place: 'left'}
123+
newState: {place: outsideRightResult.newPlace}
62124
}
63-
} else if (place === 'top' && outsideTop()) {
125+
} else if (place === 'top' && outsideTopResult.result) {
64126
return {
65127
isNewState: true,
66-
newState: {place: 'bottom'}
128+
newState: {place: outsideTopResult.newPlace}
67129
}
68-
} else if (place === 'bottom' && outsideBottom()) {
130+
} else if (place === 'bottom' && outsideBottomResult.result) {
69131
return {
70132
isNewState: true,
71-
newState: {place: 'top'}
133+
newState: {place: outsideBottomResult.newPlace}
72134
}
73135
}
74136

@@ -109,19 +171,59 @@ const getDefaultPosition = (effect, targetWidth, targetHeight, tipWidth, tipHeig
109171
let right
110172
let bottom
111173
let left
112-
const disToMouse = 15
113-
const triangleHeight = 5
174+
const disToMouse = 8
175+
const triangleHeight = 2
114176

115177
if (effect === 'float') {
116-
top = {x: -(tipWidth / 2), y: -(tipHeight + disToMouse - triangleHeight)}
117-
bottom = {x: -(tipWidth / 2), y: disToMouse}
118-
left = {x: -(tipWidth + disToMouse - triangleHeight), y: -(tipHeight / 2)}
119-
right = {x: disToMouse, y: -(tipHeight / 2)}
178+
top = {
179+
l: -(tipWidth / 2),
180+
r: tipWidth / 2,
181+
t: -(tipHeight + disToMouse + triangleHeight),
182+
b: -disToMouse
183+
}
184+
bottom = {
185+
l: -(tipWidth / 2),
186+
r: tipWidth / 2,
187+
t: disToMouse,
188+
b: tipHeight + disToMouse + triangleHeight
189+
}
190+
left = {
191+
l: -(tipWidth + disToMouse + triangleHeight),
192+
r: -disToMouse,
193+
t: -(tipHeight / 2),
194+
b: tipHeight / 2
195+
}
196+
right = {
197+
l: disToMouse,
198+
r: tipWidth + disToMouse + triangleHeight,
199+
t: -(tipHeight / 2),
200+
b: tipHeight / 2
201+
}
120202
} else if (effect === 'solid') {
121-
top = {x: -(tipWidth / 2), y: -(targetHeight / 2 + tipHeight)}
122-
bottom = {x: -(tipWidth / 2), y: targetHeight / 2}
123-
left = {x: -(tipWidth + targetWidth / 2), y: -(tipHeight / 2)}
124-
right = {x: targetWidth / 2, y: -(tipHeight / 2)}
203+
top = {
204+
l: -(tipWidth / 2),
205+
r: tipWidth / 2,
206+
t: -(targetHeight / 2 + tipHeight + triangleHeight),
207+
b: -(targetHeight / 2)
208+
}
209+
bottom = {
210+
l: -(tipWidth / 2),
211+
r: tipWidth / 2,
212+
t: targetHeight / 2,
213+
b: targetHeight / 2 + tipHeight + triangleHeight
214+
}
215+
left = {
216+
l: -(tipWidth + targetWidth / 2 + triangleHeight),
217+
r: -(targetWidth / 2),
218+
t: -(tipHeight / 2),
219+
b: tipHeight / 2
220+
}
221+
right = {
222+
l: targetWidth / 2,
223+
r: tipWidth + targetWidth / 2 + triangleHeight,
224+
t: -(tipHeight / 2),
225+
b: tipHeight / 2
226+
}
125227
}
126228

127229
return {top, bottom, left, right}

0 commit comments

Comments
 (0)