1 | import {Point, toPoint} from './Point';
|
2 |
|
3 | /*
|
4 | * @class Bounds
|
5 | * @aka L.Bounds
|
6 | *
|
7 | * Represents a rectangular area in pixel coordinates.
|
8 | *
|
9 | * @example
|
10 | *
|
11 | * ```js
|
12 | * var p1 = L.point(10, 10),
|
13 | * p2 = L.point(40, 60),
|
14 | * bounds = L.bounds(p1, p2);
|
15 | * ```
|
16 | *
|
17 | * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
|
18 | *
|
19 | * ```js
|
20 | * otherBounds.intersects([[10, 10], [40, 60]]);
|
21 | * ```
|
22 | *
|
23 | * Note that `Bounds` does not inherit from Leaflet's `Class` object,
|
24 | * which means new classes can't inherit from it, and new methods
|
25 | * can't be added to it with the `include` function.
|
26 | */
|
27 |
|
28 | export function Bounds(a, b) {
|
29 | if (!a) { return; }
|
30 |
|
31 | var points = b ? [a, b] : a;
|
32 |
|
33 | for (var i = 0, len = points.length; i < len; i++) {
|
34 | this.extend(points[i]);
|
35 | }
|
36 | }
|
37 |
|
38 | Bounds.prototype = {
|
39 | // @method extend(point: Point): this
|
40 | // Extends the bounds to contain the given point.
|
41 | extend: function (point) { // (Point)
|
42 | point = toPoint(point);
|
43 |
|
44 | // @property min: Point
|
45 | // The top left corner of the rectangle.
|
46 | // @property max: Point
|
47 | // The bottom right corner of the rectangle.
|
48 | if (!this.min && !this.max) {
|
49 | this.min = point.clone();
|
50 | this.max = point.clone();
|
51 | } else {
|
52 | this.min.x = Math.min(point.x, this.min.x);
|
53 | this.max.x = Math.max(point.x, this.max.x);
|
54 | this.min.y = Math.min(point.y, this.min.y);
|
55 | this.max.y = Math.max(point.y, this.max.y);
|
56 | }
|
57 | return this;
|
58 | },
|
59 |
|
60 | // @method getCenter(round?: Boolean): Point
|
61 | // Returns the center point of the bounds.
|
62 | getCenter: function (round) {
|
63 | return new Point(
|
64 | (this.min.x + this.max.x) / 2,
|
65 | (this.min.y + this.max.y) / 2, round);
|
66 | },
|
67 |
|
68 | // @method getBottomLeft(): Point
|
69 | // Returns the bottom-left point of the bounds.
|
70 | getBottomLeft: function () {
|
71 | return new Point(this.min.x, this.max.y);
|
72 | },
|
73 |
|
74 | // @method getTopRight(): Point
|
75 | // Returns the top-right point of the bounds.
|
76 | getTopRight: function () { // -> Point
|
77 | return new Point(this.max.x, this.min.y);
|
78 | },
|
79 |
|
80 | // @method getTopLeft(): Point
|
81 | // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).
|
82 | getTopLeft: function () {
|
83 | return this.min; // left, top
|
84 | },
|
85 |
|
86 | // @method getBottomRight(): Point
|
87 | // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).
|
88 | getBottomRight: function () {
|
89 | return this.max; // right, bottom
|
90 | },
|
91 |
|
92 | // @method getSize(): Point
|
93 | // Returns the size of the given bounds
|
94 | getSize: function () {
|
95 | return this.max.subtract(this.min);
|
96 | },
|
97 |
|
98 | // @method contains(otherBounds: Bounds): Boolean
|
99 | // Returns `true` if the rectangle contains the given one.
|
100 | // @alternative
|
101 | // @method contains(point: Point): Boolean
|
102 | // Returns `true` if the rectangle contains the given point.
|
103 | contains: function (obj) {
|
104 | var min, max;
|
105 |
|
106 | if (typeof obj[0] === 'number' || obj instanceof Point) {
|
107 | obj = toPoint(obj);
|
108 | } else {
|
109 | obj = toBounds(obj);
|
110 | }
|
111 |
|
112 | if (obj instanceof Bounds) {
|
113 | min = obj.min;
|
114 | max = obj.max;
|
115 | } else {
|
116 | min = max = obj;
|
117 | }
|
118 |
|
119 | return (min.x >= this.min.x) &&
|
120 | (max.x <= this.max.x) &&
|
121 | (min.y >= this.min.y) &&
|
122 | (max.y <= this.max.y);
|
123 | },
|
124 |
|
125 | // @method intersects(otherBounds: Bounds): Boolean
|
126 | // Returns `true` if the rectangle intersects the given bounds. Two bounds
|
127 | // intersect if they have at least one point in common.
|
128 | intersects: function (bounds) { // (Bounds) -> Boolean
|
129 | bounds = toBounds(bounds);
|
130 |
|
131 | var min = this.min,
|
132 | max = this.max,
|
133 | min2 = bounds.min,
|
134 | max2 = bounds.max,
|
135 | xIntersects = (max2.x >= min.x) && (min2.x <= max.x),
|
136 | yIntersects = (max2.y >= min.y) && (min2.y <= max.y);
|
137 |
|
138 | return xIntersects && yIntersects;
|
139 | },
|
140 |
|
141 | // @method overlaps(otherBounds: Bounds): Boolean
|
142 | // Returns `true` if the rectangle overlaps the given bounds. Two bounds
|
143 | // overlap if their intersection is an area.
|
144 | overlaps: function (bounds) { // (Bounds) -> Boolean
|
145 | bounds = toBounds(bounds);
|
146 |
|
147 | var min = this.min,
|
148 | max = this.max,
|
149 | min2 = bounds.min,
|
150 | max2 = bounds.max,
|
151 | xOverlaps = (max2.x > min.x) && (min2.x < max.x),
|
152 | yOverlaps = (max2.y > min.y) && (min2.y < max.y);
|
153 |
|
154 | return xOverlaps && yOverlaps;
|
155 | },
|
156 |
|
157 | isValid: function () {
|
158 | return !!(this.min && this.max);
|
159 | }
|
160 | };
|
161 |
|
162 |
|
163 | // @factory L.bounds(corner1: Point, corner2: Point)
|
164 | // Creates a Bounds object from two corners coordinate pairs.
|
165 | // @alternative
|
166 | // @factory L.bounds(points: Point[])
|
167 | // Creates a Bounds object from the given array of points.
|
168 | export function toBounds(a, b) {
|
169 | if (!a || a instanceof Bounds) {
|
170 | return a;
|
171 | }
|
172 | return new Bounds(a, b);
|
173 | }
|