-
Notifications
You must be signed in to change notification settings - Fork 418
Expand file tree
/
Copy pathaspect-ratio.ts
More file actions
86 lines (73 loc) · 2.33 KB
/
aspect-ratio.ts
File metadata and controls
86 lines (73 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function gcd(a: number, b: number): number {
if (b === 0) {
return a;
}
return gcd(b, a % b);
}
export interface AspectRatio {
width: number;
height: number;
}
const HORIZONTAL_ASPECT_RATIO = [
{ width: 4, height: 4 }, // Square
{ width: 4, height: 3 }, // Standard Fullscreen
{ width: 16, height: 10 }, // Standard LCD
{ width: 16, height: 9 }, // HD
// { width: 37, height: 20 }, // Widescreen
{ width: 6, height: 3 }, // Univisium
{ width: 21, height: 9 }, // Anamorphic 2.35:1
// { width: 64, height: 27 }, // Anamorphic 2.39:1 or 2.37:1
{ width: 19, height: 16 }, // Movietone
{ width: 5, height: 4 }, // 17' LCD CRT
// { width: 48, height: 35 }, // 16mm and 35mm
{ width: 11, height: 8 }, // 35mm full sound
// { width: 143, height: 100 }, // IMAX
{ width: 6, height: 4 }, // 35mm photo
{ width: 14, height: 9 }, // commercials
{ width: 5, height: 3 }, // Paramount
{ width: 7, height: 4 }, // early 35mm
{ width: 11, height: 5 }, // 70mm
{ width: 12, height: 5 }, // Bluray
{ width: 8, height: 3 }, // Super 16
{ width: 18, height: 5 }, // IMAX
{ width: 12, height: 3 }, // Polyvision
];
const VERTICAL_ASPECT_RATIO = HORIZONTAL_ASPECT_RATIO.map(item => ({
width: item.height,
height: item.width,
}));
const ASPECT_RATIO = [...HORIZONTAL_ASPECT_RATIO, ...VERTICAL_ASPECT_RATIO];
export function getAspectRatio({ width, height }: AspectRatio): AspectRatio {
const denom = gcd(width, height);
return {
width: width / denom,
height: height / denom,
};
}
export function getNearestAspectRatio(ratio: AspectRatio): AspectRatio {
let nearest = Number.MAX_VALUE;
let id = 0;
const originalRatio = ratio.width / ratio.height;
for (let i = 0; i < ASPECT_RATIO.length; i += 1) {
const target = ASPECT_RATIO[i]!;
const tRatio = target.width / target.height;
const squared = tRatio - originalRatio;
const distance = Math.sqrt(squared * squared);
if (i === 0) {
nearest = distance;
} else if (distance < nearest) {
id = i;
nearest = distance;
}
}
return ASPECT_RATIO[id]!;
}
export function getScaledComponentRatio(ratio: AspectRatio): AspectRatio {
const xScale = 9 / ratio.width;
const yScale = 9 / ratio.height;
const scale = Math.min(xScale, yScale);
return {
width: scale * ratio.width,
height: scale * ratio.height,
};
}