|
@@ -24,11 +24,21 @@ import Speedy from 'speedy-vision';
|
24
|
24
|
import { SpeedySize } from 'speedy-vision/types/core/speedy-size';
|
25
|
25
|
import { IllegalArgumentError } from './errors';
|
26
|
26
|
|
|
27
|
+type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
28
|
+type EvenDigit = '0' | '2' | '4' | '6' | '8';
|
|
29
|
+type PositiveDigit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
30
|
+type OptionalDigit = Digit | '';
|
|
31
|
+type CustomResolution = `${PositiveDigit}${OptionalDigit}${Digit}${EvenDigit}p`;
|
|
32
|
+type ResolutionAlias = 'xs' | 'xs+' | 'sm' | 'sm+' | 'md' | 'md+' | 'lg' | 'lg+' | 'xl' | 'xl+' | 'xxl' | 'xxl+';
|
|
33
|
+
|
27
|
34
|
/** Resolution type */
|
28
|
|
-export type Resolution = 'xs' | 'xs+' | 'sm' | 'sm+' | 'md' | 'md+' | 'lg' | 'lg+' | 'xl' | 'xl+' | 'xxl' | 'xxl+';
|
|
35
|
+export type Resolution = ResolutionAlias | CustomResolution;
|
|
36
|
+
|
|
37
|
+/** A regex that identifies custom resolutions */
|
|
38
|
+const CUSTOM_RESOLUTION_REGEX = /^[1-9][0-9]?[0-9][02468]p$/;
|
29
|
39
|
|
30
|
|
-/** Reference heights when in landscape mode, measured in pixels */
|
31
|
|
-const REFERENCE_HEIGHT: { readonly [R in Resolution]: number } = {
|
|
40
|
+/** Reference heights when in landscape mode, measured in pixels, for all aliases */
|
|
41
|
+const ALIAS_TO_HEIGHT: { readonly [R in ResolutionAlias]: number } = {
|
32
|
42
|
'xs' : 120,
|
33
|
43
|
'xs+': 144,
|
34
|
44
|
'sm' : 240,
|
|
@@ -44,7 +54,6 @@ const REFERENCE_HEIGHT: { readonly [R in Resolution]: number } = {
|
44
|
54
|
//'ul-': 1024,
|
45
|
55
|
//'ul': 1080, // what should we call this? xxxl? ul? (ultra large?)
|
46
|
56
|
//'ul+': 1200,
|
47
|
|
- // instead of defining xxxl, what if we accept custom resolution names such as "720p" and "1080p"?
|
48
|
57
|
};
|
49
|
58
|
|
50
|
59
|
/**
|
|
@@ -55,10 +64,10 @@ const REFERENCE_HEIGHT: { readonly [R in Resolution]: number } = {
|
55
|
64
|
*/
|
56
|
65
|
export function computeResolution(resolution: Resolution, aspectRatio: number): SpeedySize
|
57
|
66
|
{
|
58
|
|
- const referenceHeight = REFERENCE_HEIGHT[resolution];
|
|
67
|
+ const referenceHeight = parseHeight(resolution);
|
59
|
68
|
let width = 0, height = 0;
|
60
|
69
|
|
61
|
|
- if(referenceHeight === undefined)
|
|
70
|
+ if(Number.isNaN(referenceHeight))
|
62
|
71
|
throw new IllegalArgumentError('Invalid resolution: ' + resolution);
|
63
|
72
|
else if(aspectRatio <= 0)
|
64
|
73
|
throw new IllegalArgumentError('Invalid aspect ratio: ' + aspectRatio);
|
|
@@ -77,4 +86,20 @@ export function computeResolution(resolution: Resolution, aspectRatio: number):
|
77
|
86
|
}
|
78
|
87
|
|
79
|
88
|
return Speedy.Size(width, height);
|
|
89
|
+}
|
|
90
|
+
|
|
91
|
+/**
|
|
92
|
+ * Get the height in pixels of a resolution
|
|
93
|
+ * @param resolution resolution type
|
|
94
|
+ * @returns the height in pixels, or NaN on error
|
|
95
|
+ */
|
|
96
|
+function parseHeight(resolution: Resolution): number
|
|
97
|
+{
|
|
98
|
+ if(ALIAS_TO_HEIGHT.hasOwnProperty(resolution))
|
|
99
|
+ return ALIAS_TO_HEIGHT[resolution as ResolutionAlias];
|
|
100
|
+
|
|
101
|
+ if(CUSTOM_RESOLUTION_REGEX.test(resolution))
|
|
102
|
+ return parseInt(resolution);
|
|
103
|
+
|
|
104
|
+ return Number.NaN;
|
80
|
105
|
}
|