@thinkpixellab-public/px-vue 3.0.5 → 3.0.7
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/components/PxContain.vue +126 -21
- package/components/PxFloat.vue +35 -4
- package/dev/demos/Demo-PxContain.vue +2 -2
- package/package.json +1 -1
- package/utils/fit.js +2 -2
package/components/PxContain.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
Keeps a child element contained within boundaries.
|
|
3
3
|
|
|
4
|
-
<px-contain #default="{width, height, left: }" :aspect="16/9" :round="true" :px="true">
|
|
4
|
+
<px-contain #default="{width, height, left: }" :aspect="16/9" :round="true" :to-px="true">
|
|
5
5
|
<div :style="{position: 'absolute', left: left top: top width: width height: height}" />
|
|
6
6
|
</px-contain>
|
|
7
7
|
|
|
@@ -18,9 +18,7 @@
|
|
|
18
18
|
:width="contain.width"
|
|
19
19
|
:height="contain.height"
|
|
20
20
|
:scale="contain.scale"
|
|
21
|
-
>
|
|
22
|
-
<!-- fallback -->
|
|
23
|
-
</slot>
|
|
21
|
+
></slot>
|
|
24
22
|
</div>
|
|
25
23
|
</template>
|
|
26
24
|
|
|
@@ -46,6 +44,19 @@ export default {
|
|
|
46
44
|
naturalWidth: { type: Number, default: null },
|
|
47
45
|
naturalHeight: { type: Number, default: null },
|
|
48
46
|
|
|
47
|
+
// these are adjustments to the available area inside of the container rectangle; the
|
|
48
|
+
// difference between padding and border is that padding values will also affect the final
|
|
49
|
+
// top/left values but border does not (to visualize this, imagine that you use border if
|
|
50
|
+
// the content has a visible border around and the final values reflect that where padding
|
|
51
|
+
// is empty space so palcement gets shfited); specify as either a number or an arry of up to
|
|
52
|
+
// 4 numbers that follow the css box-model pattern
|
|
53
|
+
padding: { default: null },
|
|
54
|
+
border: { default: null },
|
|
55
|
+
|
|
56
|
+
// max limits fo width/height of the contain rectangle
|
|
57
|
+
maxWidth: { type: Number, default: null },
|
|
58
|
+
maxHeight: { type: Number, default: null },
|
|
59
|
+
|
|
49
60
|
// the horizontal positioning when there is leftover space
|
|
50
61
|
alignX: { default: 0.5 }, // number | 'start' | 'center' | 'end'
|
|
51
62
|
|
|
@@ -53,13 +64,16 @@ export default {
|
|
|
53
64
|
alignY: { default: 0.5 }, // number | 'start' | 'center' | 'end'
|
|
54
65
|
|
|
55
66
|
// whether slot values should be returned as strings with 'px'
|
|
56
|
-
|
|
67
|
+
toPx: { type: Boolean, default: true },
|
|
57
68
|
|
|
58
69
|
// whether slot values should be rounded to screen pixels
|
|
59
70
|
round: { type: Boolean, default: true },
|
|
60
71
|
},
|
|
61
72
|
data() {
|
|
62
73
|
return {
|
|
74
|
+
// use setContainer to use a container source other than this.$el
|
|
75
|
+
container: null,
|
|
76
|
+
|
|
63
77
|
contain: {
|
|
64
78
|
current: false,
|
|
65
79
|
width: 0,
|
|
@@ -116,6 +130,9 @@ export default {
|
|
|
116
130
|
// no width or height or aspect
|
|
117
131
|
return null;
|
|
118
132
|
},
|
|
133
|
+
containerValue() {
|
|
134
|
+
return this.container || this.$el;
|
|
135
|
+
},
|
|
119
136
|
},
|
|
120
137
|
|
|
121
138
|
watch: {
|
|
@@ -124,39 +141,127 @@ export default {
|
|
|
124
141
|
},
|
|
125
142
|
},
|
|
126
143
|
methods: {
|
|
144
|
+
// Use a source for the outer container size other than this.$el. The container argument can
|
|
145
|
+
// be an element or any object that implements getBoundingClientRect; setting a custom
|
|
146
|
+
// container may also require a direct call to resize when the container size updates (since
|
|
147
|
+
// the default resize observer behavior only observes this.$el)
|
|
148
|
+
setContainer(container) {
|
|
149
|
+
this.container = container;
|
|
150
|
+
this.resize();
|
|
151
|
+
},
|
|
127
152
|
resize() {
|
|
128
|
-
let
|
|
153
|
+
let p = this.toBoxModelObject(this.padding);
|
|
154
|
+
let b = this.toBoxModelObject(this.border);
|
|
155
|
+
|
|
156
|
+
let outer = this.containerValue.getBoundingClientRect();
|
|
129
157
|
let inner = this.aspectRect || outer;
|
|
130
158
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
outer,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
159
|
+
outer = {
|
|
160
|
+
width: outer.width - (b.w + p.w),
|
|
161
|
+
height: outer.height - (b.h + p.h),
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// max width/height
|
|
165
|
+
|
|
166
|
+
if (this.maxHeight && outer.height > this.maxHeight) {
|
|
167
|
+
outer.y = (outer.height - this.maxHeight) * this.alignToDecimal(this.alignY);
|
|
168
|
+
outer.height = this.maxHeight;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (this.maxWidth && outer.width > this.maxWidth) {
|
|
172
|
+
outer.x = (outer.width - this.maxWidth) * this.alignToDecimal(this.alignX);
|
|
173
|
+
outer.width = this.maxWidth;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// get contain
|
|
177
|
+
|
|
178
|
+
let r;
|
|
137
179
|
|
|
138
|
-
this.
|
|
180
|
+
if (this.aspect) {
|
|
181
|
+
r = contain(
|
|
182
|
+
inner,
|
|
183
|
+
outer,
|
|
184
|
+
this.alignToDecimal(this.alignX),
|
|
185
|
+
this.alignToDecimal(this.alignY)
|
|
186
|
+
);
|
|
187
|
+
} else {
|
|
188
|
+
r = {
|
|
189
|
+
x: 0,
|
|
190
|
+
y: 0,
|
|
191
|
+
width: outer.width,
|
|
192
|
+
height: outer.height,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
let c = {
|
|
139
197
|
current: true,
|
|
140
|
-
width:
|
|
141
|
-
height:
|
|
142
|
-
top:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
scale: this.naturalWidth || this.naturalHeight ?
|
|
198
|
+
width: r.width + b.w,
|
|
199
|
+
height: r.height + b.h,
|
|
200
|
+
top: r.y + p.top,
|
|
201
|
+
left: r.x + p.left,
|
|
202
|
+
right: r.width - (r.x + b.w),
|
|
203
|
+
bottom: r.height - (r.y + b.h),
|
|
204
|
+
scale: this.naturalWidth || this.naturalHeight ? r.scale : 1,
|
|
147
205
|
};
|
|
206
|
+
|
|
207
|
+
this.$emit('update', c);
|
|
208
|
+
|
|
209
|
+
c.width = this.prepValue(c.width);
|
|
210
|
+
c.height = this.prepValue(c.height);
|
|
211
|
+
c.left = this.prepValue(c.left);
|
|
212
|
+
c.top = this.prepValue(c.top);
|
|
213
|
+
c.right = this.prepValue(c.right);
|
|
214
|
+
c.bottom = this.prepValue(c.bottom);
|
|
215
|
+
|
|
216
|
+
this.contain = c;
|
|
148
217
|
},
|
|
149
218
|
|
|
150
219
|
prepValue(n) {
|
|
151
220
|
if (this.round && typeof window != 'undefined') {
|
|
152
221
|
n = Math.round(n * window.devicePixelRatio) / window.devicePixelRatio;
|
|
153
222
|
}
|
|
154
|
-
if (this.
|
|
223
|
+
if (this.toPx) {
|
|
155
224
|
n = this.cssPx(n);
|
|
156
225
|
}
|
|
157
226
|
return n;
|
|
158
227
|
},
|
|
159
228
|
|
|
229
|
+
toBoxModelObject(val) {
|
|
230
|
+
const arr = this.toBoxModelArray(val);
|
|
231
|
+
return {
|
|
232
|
+
top: arr[0],
|
|
233
|
+
right: arr[1],
|
|
234
|
+
bottom: arr[2],
|
|
235
|
+
left: arr[3],
|
|
236
|
+
w: arr[1] + arr[3],
|
|
237
|
+
h: arr[0] + arr[2],
|
|
238
|
+
};
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
toBoxModelArray(val) {
|
|
242
|
+
if (!val) {
|
|
243
|
+
return [0, 0, 0, 0];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (Array.isArray(val)) {
|
|
247
|
+
if (val.length == 0) {
|
|
248
|
+
return [0, 0, 0, 0];
|
|
249
|
+
}
|
|
250
|
+
if (val.length == 1) {
|
|
251
|
+
return [val[0], val[0], val[0], val[0]];
|
|
252
|
+
}
|
|
253
|
+
if (val.length == 2) {
|
|
254
|
+
return [val[0], val[1], val[0], val[1]];
|
|
255
|
+
}
|
|
256
|
+
if (val.length == 3) {
|
|
257
|
+
return [val[0], val[1], val[2], val[1]];
|
|
258
|
+
}
|
|
259
|
+
return [val[0], val[1], val[2], val[3]];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return [val, val, val, val];
|
|
263
|
+
},
|
|
264
|
+
|
|
160
265
|
alignToDecimal(align) {
|
|
161
266
|
if (typeof align == 'number') {
|
|
162
267
|
return align;
|
package/components/PxFloat.vue
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
:name="calcTransitionName"
|
|
23
23
|
@before-enter="transitionVisible = true"
|
|
24
24
|
@after-leave="transitionVisible = false"
|
|
25
|
-
:style="{ zIndex: zStart + currentLayerIndex }"
|
|
26
25
|
>
|
|
27
26
|
<div
|
|
28
|
-
:class="bem({ ...variantsMap, absolute: strategy == 'absolute' })"
|
|
27
|
+
:class="[rootClass, bem({ ...variantsMap, absolute: strategy == 'absolute' })]"
|
|
28
|
+
:style="{ ...(rootStyle || {}), zIndex: zStart + currentLayerIndex }"
|
|
29
29
|
v-show="visibleValueNext"
|
|
30
30
|
>
|
|
31
31
|
<!-- overlay element -->
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
:class="[bem('overlay'), overlayClass]"
|
|
35
35
|
@click="overlayClick"
|
|
36
36
|
v-bind="overlayAttributes"
|
|
37
|
+
ref="overlay"
|
|
37
38
|
:style="{
|
|
38
39
|
pointerEvents: visibleValue ? null : 'none',
|
|
39
40
|
userSelect: visibleValue ? null : 'none',
|
|
@@ -113,11 +114,17 @@ export default {
|
|
|
113
114
|
// to ensure that the last opened from the same starting z will be on top of each other)
|
|
114
115
|
zStart: { type: Number, default: 999999 },
|
|
115
116
|
|
|
117
|
+
// class set on the root element (equivalent of setting class if not using a portal)
|
|
118
|
+
rootClass: { type: String, default: null },
|
|
119
|
+
|
|
120
|
+
// style set on the root element (equivalent of setting style if not using a portal)
|
|
121
|
+
rootStyle: { default: null },
|
|
122
|
+
|
|
116
123
|
// An additional class set on the popup element
|
|
117
124
|
popupClass: { type: String, default: '' },
|
|
118
125
|
|
|
119
126
|
// Style object that gets merged onto the popup
|
|
120
|
-
popupStyle: {
|
|
127
|
+
popupStyle: { default: null },
|
|
121
128
|
|
|
122
129
|
// Whether to render an overlay element
|
|
123
130
|
overlayEnabled: { type: Boolean, default: true },
|
|
@@ -222,6 +229,13 @@ export default {
|
|
|
222
229
|
// emit update when visibleValue changes (enables .sync on parent)
|
|
223
230
|
this.$emit('update:visible', nv);
|
|
224
231
|
|
|
232
|
+
if (nv) {
|
|
233
|
+
this.$emit('beforeshow');
|
|
234
|
+
}
|
|
235
|
+
if (!nv) {
|
|
236
|
+
this.$emit('beforehide');
|
|
237
|
+
}
|
|
238
|
+
|
|
225
239
|
if (this.isServer) {
|
|
226
240
|
return;
|
|
227
241
|
}
|
|
@@ -273,7 +287,6 @@ export default {
|
|
|
273
287
|
}
|
|
274
288
|
} else {
|
|
275
289
|
if (this.cleanup) {
|
|
276
|
-
console.log('cleanup');
|
|
277
290
|
this.cleanup();
|
|
278
291
|
this.cleanup = null;
|
|
279
292
|
}
|
|
@@ -312,6 +325,15 @@ export default {
|
|
|
312
325
|
globalClearLayerIndex = 0;
|
|
313
326
|
}
|
|
314
327
|
}
|
|
328
|
+
|
|
329
|
+
// show and hide events (also see beforeshow/beforehide in visibleValue watcher)
|
|
330
|
+
|
|
331
|
+
if (nv) {
|
|
332
|
+
this.$emit('show');
|
|
333
|
+
}
|
|
334
|
+
if (!nv) {
|
|
335
|
+
this.$emit('hide');
|
|
336
|
+
}
|
|
315
337
|
});
|
|
316
338
|
},
|
|
317
339
|
},
|
|
@@ -481,6 +503,15 @@ export default {
|
|
|
481
503
|
|
|
482
504
|
return reference;
|
|
483
505
|
},
|
|
506
|
+
|
|
507
|
+
// returns the default overlay element (will be null if the overlay slot has been overriden)
|
|
508
|
+
getOverlayElement() {
|
|
509
|
+
return this.$refs.overlay;
|
|
510
|
+
},
|
|
511
|
+
|
|
512
|
+
getPopupElement() {
|
|
513
|
+
return this.$refs.popup;
|
|
514
|
+
},
|
|
484
515
|
},
|
|
485
516
|
};
|
|
486
517
|
</script>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</px-test>
|
|
23
23
|
|
|
24
24
|
<px-test name="Width / Height" testId="pxcontain-wh" :size="{ h: 600 }">
|
|
25
|
-
<px-contain :naturalWidth="1600" :naturalHeight="900"
|
|
25
|
+
<px-contain :naturalWidth="1600" :naturalHeight="900">
|
|
26
26
|
<template #default="{ top, left, width, height }">
|
|
27
27
|
<div
|
|
28
28
|
:style="{
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
</px-test>
|
|
40
40
|
|
|
41
41
|
<px-test name="Scale" testId="pxcontain-scale" :size="{ h: 600 }">
|
|
42
|
-
<px-contain :naturalWidth="1600" :naturalHeight="900"
|
|
42
|
+
<px-contain :naturalWidth="1600" :naturalHeight="900">
|
|
43
43
|
<template #default="{ top, left, scale }">
|
|
44
44
|
<div
|
|
45
45
|
:style="{
|
package/package.json
CHANGED
package/utils/fit.js
CHANGED
|
@@ -50,14 +50,14 @@ export function contain(inner, outer, posX = 0.5, posY = 0.5) {
|
|
|
50
50
|
if (aspectInner > aspectOuter) {
|
|
51
51
|
width = outer.width;
|
|
52
52
|
height = outer.width / aspectInner;
|
|
53
|
-
x =
|
|
53
|
+
x = outer.x;
|
|
54
54
|
y = outer.height * posY - height * posY;
|
|
55
55
|
scale = height / inner.height;
|
|
56
56
|
} else {
|
|
57
57
|
width = outer.height * aspectInner;
|
|
58
58
|
height = outer.height;
|
|
59
59
|
x = outer.width * posX - width * posX;
|
|
60
|
-
y =
|
|
60
|
+
y = outer.y;
|
|
61
61
|
scale = width / inner.width;
|
|
62
62
|
}
|
|
63
63
|
|