Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F7112611
guessResolutions.ts
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
guessResolutions.ts
View Options
type
resolutionGuessOptions
=
{
min_viewport_size
?:
number
;
max_viewport_size
?:
number
;
};
type
Unit
=
"vw"
|
"px"
;
type
Ranges
=
{
screen
:
number
[][];
calculated
:
number
[][];
};
type
Condition
=
{
condition_type
:
"max"
|
"min"
|
"default"
;
width_condition
:
number
;
then_res
:
number
;
then_unit
:
"vw"
|
"px"
;
};
const
sortAscFn
=
(
a
:
number
,
b
:
number
)
=>
a
-
b
;
const
fillGaps
=
(
resolutions
:
number
[])
=>
{
const
sorted_resolutions
=
resolutions
.
sort
(
sortAscFn
);
const
gap_fills
:
number
[]
=
[];
const
smallest_res
=
sorted_resolutions
[
0
],
largest_res
=
sorted_resolutions
[
sorted_resolutions
.
length
-
1
];
if
(
largest_res
)
{
let
cur_res
=
smallest_res
*
4
;
while
(
cur_res
<
largest_res
)
{
gap_fills
.
push
(
cur_res
);
cur_res
*=
2
;
}
return
gap_fills
;
}
else
return
[];
};
const
getResFromVw
=
(
vw
:
number
,
max_res
:
number
)
=>
(
vw
/
100
)
*
max_res
;
const
createRange
=
(
val1
:
number
,
val2
:
number
,
{
subtract
=
1
}
:
{
subtract
?:
number
}
=
{}
)
=>
{
if
(
val1
>
val2
)
return
[
val2
,
val1
-
subtract
];
else
return
[
val1
,
val2
-
subtract
];
};
const
rangesSortFn
=
(
a
:
number
[],
b
:
number
[])
=>
a
[
0
]
-
b
[
0
];
const
sortRanges
=
(
initialRanges
:
Ranges
,
constant_resolutions
:
number
[])
=>
{
const
screen
=
initialRanges
.
screen
.
sort
(
rangesSortFn
);
const
calculated
=
initialRanges
.
calculated
.
sort
(
rangesSortFn
);
const
ranges
=
{
screen
,
calculated
};
return
{
ranges
,
constant_resolutions
:
constant_resolutions
.
sort
(
sortAscFn
),
};
};
const
getRanges
=
({
conditions
,
min_viewport_size
,
max_viewport_size
,
}
:
{
conditions
:
Condition
[];
max_viewport_size
:
number
;
min_viewport_size
:
number
;
})
=>
{
const
constant_resolutions
:
number
[]
=
[];
let
min_conditions_count
=
0
,
max_conditions_count
=
0
;
const
ranges
:
Ranges
=
{
calculated
:
[],
screen
:
[],
};
const
conditions_len
=
conditions
.
length
;
for
(
let
i
=
0
;
i
<
conditions_len
;
i
++
)
{
const
condit
=
conditions
[
i
];
const
prev_condit
=
conditions
[
i
-
1
];
if
(
condit
.
then_unit
===
"px"
)
{
constant_resolutions
.
push
(
condit
.
then_res
);
if
(
conditions_len
===
1
)
return
sortRanges
(
ranges
,
constant_resolutions
);
continue
;
}
const
calculated_res
=
getResFromVw
(
condit
.
then_res
,
condit
.
width_condition
);
if
(
condit
.
condition_type
===
"max"
)
{
max_conditions_count
++
;
if
(
prev_condit
&&
prev_condit
.
condition_type
!==
"default"
)
{
const
end_of_range_res
=
getResFromVw
(
condit
.
then_res
,
prev_condit
.
width_condition
);
ranges
.
screen
.
push
(
createRange
(
prev_condit
.
width_condition
,
condit
.
width_condition
)
);
ranges
.
calculated
.
push
(
createRange
(
end_of_range_res
,
calculated_res
)
);
}
if
(
i
===
0
)
{
ranges
.
screen
.
push
(
createRange
(
min_viewport_size
,
condit
.
width_condition
)
);
ranges
.
calculated
.
push
(
createRange
(
min_viewport_size
,
calculated_res
)
);
}
}
else
if
(
condit
.
condition_type
===
"min"
)
{
min_conditions_count
++
;
if
(
prev_condit
&&
prev_condit
.
condition_type
!==
"default"
)
{
const
end_of_range_res
=
getResFromVw
(
condit
.
then_res
,
prev_condit
.
width_condition
);
ranges
.
calculated
.
push
(
createRange
(
calculated_res
,
end_of_range_res
)
);
ranges
.
screen
.
push
(
createRange
(
condit
.
width_condition
,
prev_condit
.
width_condition
)
);
}
if
(
i
===
0
)
{
ranges
.
calculated
.
push
(
createRange
(
calculated_res
,
getResFromVw
(
condit
.
then_res
,
max_viewport_size
),
{
subtract
:
0
}
)
);
ranges
.
screen
.
push
(
createRange
(
condit
.
width_condition
,
max_viewport_size
,
{
subtract
:
0
,
})
);
}
}
else
if
(
condit
.
condition_type
===
"default"
)
{
if
(
!
min_conditions_count
&&
!
max_conditions_count
)
{
ranges
.
screen
.
push
(
createRange
(
min_viewport_size
,
max_viewport_size
,
{
subtract
:
0
,
})
);
ranges
.
calculated
.
unshift
(
createRange
(
min_viewport_size
,
getResFromVw
(
condit
.
then_res
,
max_viewport_size
),
{
subtract
:
0
}
)
);
return
sortRanges
(
ranges
,
constant_resolutions
);
}
const
sorted_screen_ranges
=
ranges
.
screen
.
sort
(
rangesSortFn
);
const
start_range
=
sorted_screen_ranges
[
0
][
0
];
const
end_range
=
sorted_screen_ranges
[
sorted_screen_ranges
.
length
-
1
][
1
]
+
1
;
if
(
min_conditions_count
)
{
ranges
.
screen
.
push
(
createRange
(
min_viewport_size
,
start_range
));
ranges
.
calculated
.
unshift
(
createRange
(
min_viewport_size
,
getResFromVw
(
condit
.
then_res
,
start_range
)
)
);
}
else
if
(
max_conditions_count
)
{
ranges
.
screen
.
push
(
createRange
(
end_range
,
max_viewport_size
,
{
subtract
:
0
})
);
ranges
.
calculated
.
push
(
createRange
(
getResFromVw
(
condit
.
then_res
,
end_range
),
getResFromVw
(
condit
.
then_res
,
max_viewport_size
),
{
subtract
:
0
}
)
);
}
}
}
return
sortRanges
(
ranges
,
constant_resolutions
);
};
const
guessResolutions
=
(
sizes_attr
:
string
,
{
min_viewport_size
=
320
,
max_viewport_size
=
1920
,
}
:
resolutionGuessOptions
=
{}
)
:
number
[]
=>
{
const
gap_fills
:
number
[]
=
[],
resolutions
:
number
[]
=
[],
constant_resolutions
:
number
[]
=
[];
const
regex
=
/\((max|min)-width\s*:\s*(\d+)px\s*\)\s*(\d+)(vw|px)/gi
;
let
match
=
regex
.
exec
(
sizes_attr
);
const
condition_matches
=
[];
while
(
match
!==
null
)
{
condition_matches
.
push
(
match
);
match
=
regex
.
exec
(
sizes_attr
);
}
const
default_size_match
=
/(,?)\s*(\d+)(px|vw)\s*$/i
.
exec
(
sizes_attr
);
const
conditions
:
Condition
[]
=
[];
for
(
const
match
of
condition_matches
)
{
const
condition_type
=
match
[
1
]
as
"max"
|
"min"
,
width_condition
=
parseInt
(
match
[
2
]),
then_res
=
parseInt
(
match
[
3
]),
then_unit
=
match
[
4
]
as
Unit
;
conditions
.
push
({
condition_type
,
width_condition
,
then_res
,
then_unit
,
});
}
if
(
default_size_match
)
{
const
res
=
parseInt
(
default_size_match
[
2
]),
unit
=
default_size_match
[
3
]
as
Unit
;
conditions
.
push
({
condition_type
:
"default"
,
width_condition
:
0
,
then_res
:
res
,
then_unit
:
unit
,
});
}
const
{
ranges
,
constant_resolutions
:
constant_resolutions_unsorted
,
}
=
getRanges
({
conditions
,
min_viewport_size
,
max_viewport_size
,
});
for
(
const
range
of
ranges
.
calculated
)
{
resolutions
.
push
(...
range
,
range
[
0
]
*
2
,
range
[
1
]
*
2
);
}
for
(
const
res
of
constant_resolutions_unsorted
)
{
constant_resolutions
.
push
(
res
,
res
*
2
);
}
const
filtered_resolutions
=
resolutions
.
map
((
res
)
=>
{
if
(
res
<
min_viewport_size
)
{
return
min_viewport_size
;
}
else
return
Math
.
round
(
res
);
});
gap_fills
.
push
(...
fillGaps
(
filtered_resolutions
));
const
final_resolutions
=
[
...
new
Set
(
filtered_resolutions
.
concat
(...
gap_fills
,
...
constant_resolutions
)
),
].
sort
(
sortAscFn
);
return
final_resolutions
;
};
export
{
guessResolutions
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 3, 22:50 (10 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
773362
Default Alt Text
guessResolutions.ts (6 KB)
Attached To
Mode
rRIMAGEROUTER koa-responsive-image-router
Attached
Detach File
Event Timeline
Log In to Comment