center-center 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +216 -0
- package/package.json +29 -0
package/index.mjs
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import debug from 'debug'
|
|
2
|
+
|
|
3
|
+
const log = debug('center-center')
|
|
4
|
+
|
|
5
|
+
export function getViewportRect () {
|
|
6
|
+
const {
|
|
7
|
+
innerWidth: viewportW,
|
|
8
|
+
innerHeight: viewportH
|
|
9
|
+
} = window
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
scrollingElement: {
|
|
13
|
+
scrollLeft: viewportL,
|
|
14
|
+
scrollTop: viewportT
|
|
15
|
+
}
|
|
16
|
+
} = document
|
|
17
|
+
|
|
18
|
+
const viewportR = (viewportL + viewportW)
|
|
19
|
+
const viewportB = (viewportT + viewportH)
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
top: viewportT,
|
|
23
|
+
right: viewportR,
|
|
24
|
+
bottom: viewportB,
|
|
25
|
+
left: viewportL,
|
|
26
|
+
width: viewportW,
|
|
27
|
+
height: viewportH
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getContainerRect (container) {
|
|
32
|
+
const {
|
|
33
|
+
offsetLeft: containerL,
|
|
34
|
+
offsetTop: containerT
|
|
35
|
+
} = container
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* x/top is relative to the viewport
|
|
39
|
+
*/
|
|
40
|
+
const {
|
|
41
|
+
x: containerX,
|
|
42
|
+
y: containerY,
|
|
43
|
+
width: containerW,
|
|
44
|
+
height: containerH
|
|
45
|
+
} = container.getBoundingClientRect()
|
|
46
|
+
|
|
47
|
+
const containerR = (containerL + containerW)
|
|
48
|
+
const containerB = (containerT + containerH)
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
x: containerX,
|
|
52
|
+
y: containerY,
|
|
53
|
+
top: containerT,
|
|
54
|
+
right: containerR,
|
|
55
|
+
bottom: containerB,
|
|
56
|
+
left: containerL,
|
|
57
|
+
width: containerW,
|
|
58
|
+
height: containerH
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getTargetRect (target) {
|
|
63
|
+
const {
|
|
64
|
+
offsetWidth: targetW,
|
|
65
|
+
offsetHeight: targetH
|
|
66
|
+
} = target
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
width: targetW,
|
|
70
|
+
height: targetH
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function getRects (container, target) {
|
|
75
|
+
return {
|
|
76
|
+
viewport: getViewportRect(),
|
|
77
|
+
container: getContainerRect(container),
|
|
78
|
+
target: getTargetRect(target)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function calculateLeft ({
|
|
83
|
+
viewport: {
|
|
84
|
+
left: viewportL,
|
|
85
|
+
right: viewportR,
|
|
86
|
+
height: viewportH
|
|
87
|
+
},
|
|
88
|
+
container: {
|
|
89
|
+
left: containerL,
|
|
90
|
+
right: containerR,
|
|
91
|
+
width: containerW
|
|
92
|
+
},
|
|
93
|
+
target: {
|
|
94
|
+
width: targetW
|
|
95
|
+
}
|
|
96
|
+
}) {
|
|
97
|
+
if (viewportL > containerL) {
|
|
98
|
+
if (containerR > viewportL) {
|
|
99
|
+
if (viewportR > containerR) {
|
|
100
|
+
log('calculate viewportL to containerR')
|
|
101
|
+
|
|
102
|
+
const availableW = Math.max(targetW, (containerL + containerW) - viewportL)
|
|
103
|
+
|
|
104
|
+
return (containerW - availableW) + ((availableW / 2) - (targetW / 2))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (containerR > viewportR) {
|
|
108
|
+
log('calculate viewportL to viewportR')
|
|
109
|
+
|
|
110
|
+
const availableW = Math.max(targetW, viewportH)
|
|
111
|
+
|
|
112
|
+
return (viewportL - containerL) + ((availableW / 2) - (targetW / 2))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (viewportL > containerR) {
|
|
117
|
+
log('pin to right')
|
|
118
|
+
|
|
119
|
+
const availableW = Math.max(targetW, containerW)
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Pin to right
|
|
123
|
+
*/
|
|
124
|
+
return (availableW - targetW)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (containerL > viewportL) {
|
|
129
|
+
if (containerL > viewportR) {
|
|
130
|
+
log('pin to left')
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Pin to left
|
|
134
|
+
*
|
|
135
|
+
* Scroll is above container (container is offscreen)
|
|
136
|
+
*/
|
|
137
|
+
return 0
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (viewportR > containerL) {
|
|
141
|
+
log('calculate containerL to viewportR')
|
|
142
|
+
|
|
143
|
+
const availableW = Math.max(targetW, (viewportR - containerL))
|
|
144
|
+
|
|
145
|
+
return ((availableW / 2) - (targetW / 2))
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function calculateTop ({
|
|
151
|
+
viewport: {
|
|
152
|
+
top: viewportT,
|
|
153
|
+
bottom: viewportB,
|
|
154
|
+
height: viewportH
|
|
155
|
+
},
|
|
156
|
+
container: {
|
|
157
|
+
top: containerT,
|
|
158
|
+
bottom: containerB,
|
|
159
|
+
height: containerH
|
|
160
|
+
},
|
|
161
|
+
target: {
|
|
162
|
+
height: targetH
|
|
163
|
+
}
|
|
164
|
+
}) {
|
|
165
|
+
if (viewportT > containerT) {
|
|
166
|
+
if (containerB > viewportT) {
|
|
167
|
+
if (viewportB > containerB) {
|
|
168
|
+
log('calculate viewportT to containerB')
|
|
169
|
+
|
|
170
|
+
const availableH = Math.max(targetH, (containerT + containerH) - viewportT)
|
|
171
|
+
|
|
172
|
+
return (containerH - availableH) + ((availableH / 2) - (targetH / 2))
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (containerB > viewportB) {
|
|
176
|
+
log('calculate viewportT to viewportB') // , viewportT > containerT, containerB > viewportB)
|
|
177
|
+
|
|
178
|
+
const availableH = Math.max(targetH, viewportH)
|
|
179
|
+
|
|
180
|
+
return (viewportT - containerT) + ((availableH / 2) - (targetH / 2))
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (viewportT > containerB) {
|
|
185
|
+
log('pin to bottom')
|
|
186
|
+
|
|
187
|
+
const availableH = Math.max(targetH, containerH)
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Pin to bottom
|
|
191
|
+
*/
|
|
192
|
+
return (availableH - targetH)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (containerT > viewportT) {
|
|
197
|
+
if (containerT > viewportB) {
|
|
198
|
+
log('pin to top')
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Pin to top
|
|
202
|
+
*
|
|
203
|
+
* Scroll is above container (container is offscreen)
|
|
204
|
+
*/
|
|
205
|
+
return 0
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (viewportB > containerT) {
|
|
209
|
+
log('calculate containerT to viewportB')
|
|
210
|
+
|
|
211
|
+
const availableH = Math.max(targetH, (viewportB - containerT))
|
|
212
|
+
|
|
213
|
+
return ((availableH / 2) - (targetH / 2))
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "center-center",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Position an element at the center center of a container",
|
|
5
|
+
"main": "./index.mjs",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Jonathan Perry for Sequence Media Limited",
|
|
9
|
+
"email": "sequencemedia@sequencemedia.net",
|
|
10
|
+
"url": "http://sequencemedia.net"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"lint": "cross-env NODE_ENV=production eslint . --ext .mjs,.cjs",
|
|
14
|
+
"lint:fix": "npm run lint -- --fix"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"debug": "^4.3.4"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@babel/cli": "^7.22.15",
|
|
21
|
+
"@babel/core": "^7.22.17",
|
|
22
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
23
|
+
"@babel/preset-env": "^7.22.15",
|
|
24
|
+
"core-js": "^3.32.2",
|
|
25
|
+
"cross-env": "^7.0.3",
|
|
26
|
+
"eslint": "^8.49.0",
|
|
27
|
+
"eslint-config-standard": "^17.1.0"
|
|
28
|
+
}
|
|
29
|
+
}
|