-
Notifications
You must be signed in to change notification settings - Fork 5
/
Viewport.js
70 lines (62 loc) · 2.6 KB
/
Viewport.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
'use strict';
import { GAME_WIDTH, GAME_HEIGHT } from './Constants';
/**
* Viewport
*
* Represents the game display (for us, a canvas).
*/
export const Viewport = {
init() {
Viewport.canvas = document.getElementById('canvas');
Viewport.ctx = Viewport.canvas.getContext('2d');
Viewport.resize(true);
},
// Resize the canvas to give us approximately our desired game display size.
//
// Rather than attempt to explain it, here's a concrete example:
//
// we start with a desired game dimension: 480x270px
// get the actual browser dimensions: 1309x468px
// factor in the display's DPI ratio: 2618x936px
// now calculate the horizontal scale: 5.45x
// and the vertical scale: 3.46x
// our new offical game scaling is: 5.4x
// and our official viewport dimensions: 484x173px
//
// This approach emphasizes correct aspect ratio and maintains full-window rendering, at
// the potential cost of limiting visibility of the game itself in either the X or Y axis.
// If you use this approach, make sure your GUI can "float" (otherwise there may be whole
// UI elements the player cannot see!).
resize(force) {
let dpi = window.devicePixelRatio,
width = Viewport.canvas.clientWidth,
height = Viewport.canvas.clientHeight,
dpiWidth = width * dpi,
dpiHeight = height * dpi;
if (
force ||
Viewport.canvas.width !== dpiWidth ||
Viewport.canvas.height !== dpiHeight
) {
Viewport.canvas.width = dpiWidth;
Viewport.canvas.height = dpiHeight;
Viewport.scale = ((Math.max(dpiWidth / GAME_WIDTH, dpiHeight / GAME_HEIGHT) * 10) | 0) / 10;
Viewport.width = Math.ceil(dpiWidth / Viewport.scale);
Viewport.height = Math.ceil(dpiHeight / Viewport.scale);
Viewport.center = {
u: (Viewport.width / 2) | 0,
v: (Viewport.height / 2) | 0
};
Viewport.clientWidth = width;
Viewport.clientHeight = height;
// Note: smoothing flag gets reset on every resize by some browsers, which is why
// we do it here.
Viewport.ctx.imageSmoothingEnabled = false;
}
// We do this every frame, not just on resize, due to browser sometimes "forgetting".
Viewport.canvas.style.cursor = 'none';
},
fillViewportRect() {
Viewport.ctx.fillRect(0, 0, Viewport.width, Viewport.height);
}
};