-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathedge_insets.js
102 lines (90 loc) · 3.39 KB
/
edge_insets.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
// @flow
import {number} from "../style-spec/util/interpolate";
import Point from "@mapbox/point-geometry";
import {clamp} from "../util/util";
/**
* An `EdgeInset` object represents screen space padding applied to the edges of the viewport.
* This shifts the apprent center or the vanishing point of the map. This is useful for adding floating UI elements
* on top of the map and having the vanishing point shift as UI elements resize.
*
* @param {number} [top=0]
* @param {number} [bottom=0]
* @param {number} [left=0]
* @param {number} [right=0]
*/
class EdgeInsets {
top: number;
bottom: number;
left: number;
right: number;
constructor(top: number = 0, bottom: number = 0, left: number = 0, right: number = 0) {
if (isNaN(top) || top < 0 ||
isNaN(bottom) || bottom < 0 ||
isNaN(left) || left < 0 ||
isNaN(right) || right < 0
) {
throw new Error('Invalid value for edge-insets, top, bottom, left and right must all be numbers');
}
this.top = top;
this.bottom = bottom;
this.left = left;
this.right = right;
}
/**
* Interpolates the inset in-place.
* This maintains the current inset value for any inset not present in `target`.
*
* @param {PaddingOptions} target
* @param {number} t
* @returns {EdgeInsets}
* @memberof EdgeInsets
*/
interpolate(start: PaddingOptions | EdgeInsets, target: PaddingOptions, t: number): EdgeInsets {
if (target.top != null && start.top != null) this.top = number(start.top, target.top, t);
if (target.bottom != null && start.bottom != null) this.bottom = number(start.bottom, target.bottom, t);
if (target.left != null && start.left != null) this.left = number(start.left, target.left, t);
if (target.right != null && start.right != null) this.right = number(start.right, target.right, t);
return this;
}
/**
* Utility method that computes the new apprent center or vanishing point after applying insets.
* This is in pixels and with the top left being (0.0) and +y being downwards.
*
* @param {number} width
* @param {number} height
* @returns {Point}
* @memberof EdgeInsets
*/
getCenter(width: number, height: number): Point {
// Clamp insets so they never overflow width/height and always calculate a valid center
const x = clamp((this.left + width - this.right) / 2, 0, width);
const y = clamp((this.top + height - this.bottom) / 2, 0, height);
return new Point(x, y);
}
equals(other: PaddingOptions): boolean {
return this.top === other.top &&
this.bottom === other.bottom &&
this.left === other.left &&
this.right === other.right;
}
clone(): EdgeInsets {
return new EdgeInsets(this.top, this.bottom, this.left, this.right);
}
/**
* Returns the current sdtate as json, useful when you want to have a
* read-only representation of the inset.
*
* @returns {PaddingOptions}
* @memberof EdgeInsets
*/
toJSON(): PaddingOptions {
return {
top: this.top,
bottom: this.bottom,
left: this.left,
right: this.right
};
}
}
export type PaddingOptions = {top: ?number, bottom: ?number, right: ?number, left: ?number};
export default EdgeInsets;