@thinkpixellab-public/px-vue 3.0.107 → 3.0.108
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/package.json +1 -1
- package/utils/SharedHeightManager.js +213 -0
package/package.json
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
class HeightGroup {
|
|
2
|
+
constructor(id, ops = {}) {
|
|
3
|
+
this.id = id;
|
|
4
|
+
|
|
5
|
+
this.ops = {
|
|
6
|
+
// set to null to disable css variables
|
|
7
|
+
varsParent: window.document.body,
|
|
8
|
+
|
|
9
|
+
// debounce time in ms
|
|
10
|
+
debounce: 0,
|
|
11
|
+
|
|
12
|
+
// css variable prefix (e.g. --hg-groupId-h)
|
|
13
|
+
prefix: 'hg',
|
|
14
|
+
|
|
15
|
+
// ignore heights that are larger than this value in pixels
|
|
16
|
+
ignoreMax: null,
|
|
17
|
+
|
|
18
|
+
// ignore heights that are larger than this value as a standard deviation of the mean height
|
|
19
|
+
ignoreVariance: null,
|
|
20
|
+
|
|
21
|
+
// debug mode (adds some loging that can help with debugging)
|
|
22
|
+
debug: false,
|
|
23
|
+
|
|
24
|
+
changeCallback: null,
|
|
25
|
+
|
|
26
|
+
...ops,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
this.max = null;
|
|
30
|
+
this.elements = [];
|
|
31
|
+
this.currentMaxElements = [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
updateOptions(ops) {
|
|
35
|
+
this.ops = { ...this.ops, ...ops };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getVariableName() {
|
|
39
|
+
return '--' + (this.ops.prefix ? this.ops.prefix + '-' : '') + this.id + '-h';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
trySync() {
|
|
43
|
+
clearTimeout(this.lastTimeout);
|
|
44
|
+
|
|
45
|
+
this.lastTimeout = setTimeout(() => {
|
|
46
|
+
let heights = this.elements.map(el => el.height);
|
|
47
|
+
let ignore = Number.MAX_VALUE;
|
|
48
|
+
|
|
49
|
+
if (this.ops.ignoreVariance) {
|
|
50
|
+
const mean = heights.reduce((sum, height) => sum + height, 0) / heights.length;
|
|
51
|
+
const variance =
|
|
52
|
+
heights.reduce((sum, height) => sum + Math.pow(height - mean, 2), 0) /
|
|
53
|
+
heights.length;
|
|
54
|
+
const stdDev = Math.sqrt(variance);
|
|
55
|
+
|
|
56
|
+
if (this.ops.debug) {
|
|
57
|
+
console.log(`stdDev: ${stdDev}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
ignore = this.ops.ignoreVariance * stdDev + mean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (this.ops.ignoreMax) {
|
|
64
|
+
ignore = Math.min(ignore, this.ops.ignoreMax);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const max = Math.max(...heights.filter(height => height <= ignore));
|
|
68
|
+
|
|
69
|
+
if (this.max !== max) {
|
|
70
|
+
this.max = max;
|
|
71
|
+
|
|
72
|
+
// store the elements that have the max height
|
|
73
|
+
this.currentMaxElements = this.elements.filter(el => el.height === max);
|
|
74
|
+
|
|
75
|
+
if (this.ops.varsParent) {
|
|
76
|
+
this.ops.varsParent.style.setProperty(this.getVariableName(), max + 'px');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (this.ops.changeCallback) {
|
|
80
|
+
this.ops.changeCallback(this.id, this.max);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (this.ops.debug) {
|
|
85
|
+
console.log(`ignore: ${ignore}`);
|
|
86
|
+
console.log(
|
|
87
|
+
'valid heights:',
|
|
88
|
+
heights.filter(height => height <= ignore)
|
|
89
|
+
);
|
|
90
|
+
console.log(
|
|
91
|
+
'invalid heights:',
|
|
92
|
+
heights.filter(height => height > ignore)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}, this.ops.debounce);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
updateElement(element, height) {
|
|
99
|
+
if (!element) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let el = this.elements.find(el => el.element == element);
|
|
104
|
+
|
|
105
|
+
if (!el) {
|
|
106
|
+
el = { element, height: null };
|
|
107
|
+
this.elements.push(el);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (el.height !== height) {
|
|
111
|
+
el.height = height;
|
|
112
|
+
|
|
113
|
+
if (this.currentMaxElements.includes(el)) {
|
|
114
|
+
// this element was the max height, so we need to recalculate the max height even if smaller
|
|
115
|
+
this.max = null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.trySync();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
removeElement(element) {
|
|
123
|
+
const el = this.elements.find(el => el.element === element);
|
|
124
|
+
if (el) {
|
|
125
|
+
this.elements = this.elements.filter(el => el.element !== element);
|
|
126
|
+
|
|
127
|
+
if (this.currentMaxElements.includes(el.element)) {
|
|
128
|
+
this.currentMaxElements = [];
|
|
129
|
+
this.max = null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
this.trySync();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default {
|
|
138
|
+
getGroups() {
|
|
139
|
+
if (!window.$heightGroups) {
|
|
140
|
+
window.$heightGroups = {};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return window.$heightGroups;
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
getGroup(id) {
|
|
147
|
+
if (!id) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const groups = this.getGroups();
|
|
152
|
+
|
|
153
|
+
if (id in groups) {
|
|
154
|
+
return groups[id];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return null;
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
addGroup(group) {
|
|
161
|
+
const groups = this.getGroups();
|
|
162
|
+
groups[group.id] = group;
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
createGroup(id, ops) {
|
|
166
|
+
if (!id) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const group = new HeightGroup(id, ops);
|
|
171
|
+
this.addGroup(group);
|
|
172
|
+
|
|
173
|
+
return group;
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export class SharedHeightScopeManager {
|
|
178
|
+
constructor(scopeElement, changeCallback) {
|
|
179
|
+
this.groups = {};
|
|
180
|
+
this.scopeElement = scopeElement;
|
|
181
|
+
this.groupMaxChanged = changeCallback;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
getGroup(id) {
|
|
185
|
+
if (!id) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (id in this.groups) {
|
|
190
|
+
return this.groups[id];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
addGroup(group) {
|
|
197
|
+
this.groups[group.id] = group;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
createGroup(id, ops = {}) {
|
|
201
|
+
if (!id) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
ops.varsParent = this.scopeElement;
|
|
206
|
+
ops.changeCallback = this.groupMaxChanged;
|
|
207
|
+
|
|
208
|
+
const group = new HeightGroup(id, ops);
|
|
209
|
+
this.addGroup(group);
|
|
210
|
+
|
|
211
|
+
return group;
|
|
212
|
+
}
|
|
213
|
+
}
|