This repository has been archived by the owner on Nov 3, 2021. It is now read-only.
/
camera-utils.js
117 lines (93 loc) · 3.3 KB
/
camera-utils.js
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
define(function() {
'use strict';
var CameraUtils = function CameraUtils() {};
CameraUtils.scaleSizeToFitViewport = function(viewportSize, imageSize) {
var sw = viewportSize.width / imageSize.width,
sh = viewportSize.height / imageSize.height,
scale;
// Select the smaller scale to fit image completely within the viewport
scale = Math.min(sw, sh);
return {
width: imageSize.width * scale,
height: imageSize.height * scale
};
};
CameraUtils.scaleSizeToFillViewport = function(viewportSize, imageSize) {
var sw = viewportSize.width / imageSize.width,
sh = viewportSize.height / imageSize.height,
scale;
// Select the larger scale to fill and overflow viewport with image
scale = Math.max(sw, sh);
return {
width: imageSize.width * scale,
height: imageSize.height * scale
};
};
/*
Find the optimal preview size to maximize the area inside the viewport
while minimizing the area overflowing outside the viewport.
Rules:
- Preview size aspect ratio must not change
- Preview size must fit viewport dimensions or exceed them (overflow)
- "Optimal" preview size is determined by having the smallest overflow
area with the smallest scale adjustment (closest to 1.0)
- If there is an exact match found, all further calculations are
canceled and the preview size is returned immediately
*/
CameraUtils.selectOptimalPreviewSize = function(viewportSize, previewSizes) {
if (previewSizes && previewSizes.length === 0) {
return null;
}
var vw = viewportSize.width,
vh = viewportSize.height,
calculatedPreviewSizes = [],
minimumOverflow = Number.MAX_VALUE,
pw, ph, sw, sh, scale, overflow;
for (var i = 0, length = previewSizes.length; i < length; i++) {
pw = previewSizes[i].width;
ph = previewSizes[i].height;
// Preview size is an EXACT match
if (pw == vw && ph == vh) {
return previewSizes[i];
}
// Calculate the scale required to FILL the viewport
sw = vw / pw;
sh = vh / ph;
// Select the larger scale
scale = Math.max(sw, sh);
// Calculate the scaled preview size
pw *= scale;
ph *= scale;
// Calculate the overflow area (number of pixels)
overflow = (pw * ph) - (vw * vh);
// Round overflow down to integer to reduce rounding errors
overflow = Math.floor(overflow);
if (overflow < minimumOverflow) {
minimumOverflow = overflow;
}
calculatedPreviewSizes.push({
previewSize: previewSizes[i],
pw: pw,
ph: ph,
scale: scale,
overflow: overflow
});
}
// Filter out preview sizes that exceed the minimum overflow
calculatedPreviewSizes = calculatedPreviewSizes.filter(
function(previewSize) {
return previewSize.overflow <= minimumOverflow;
});
// Sort the preview sizes by scale closest to 1.0
calculatedPreviewSizes = calculatedPreviewSizes.sort(function(a, b) {
return a.scale - b.scale;
}).sort(function(a, b) {
return Math.abs(a.scale - 1) - Math.abs(b.scale - 1);
});
return calculatedPreviewSizes[0].previewSize;
};
CameraUtils.prototype = {
constructor: CameraUtils
};
return CameraUtils;
});