UNPKG

6.14 kBJavaScriptView Raw
1import {isArray, formatNum} from '../core/Util';
2
3/*
4 * @class Point
5 * @aka L.Point
6 *
7 * Represents a point with `x` and `y` coordinates in pixels.
8 *
9 * @example
10 *
11 * ```js
12 * var point = L.point(200, 300);
13 * ```
14 *
15 * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:
16 *
17 * ```js
18 * map.panBy([200, 300]);
19 * map.panBy(L.point(200, 300));
20 * ```
21 *
22 * Note that `Point` does not inherit from Leaflet's `Class` object,
23 * which means new classes can't inherit from it, and new methods
24 * can't be added to it with the `include` function.
25 */
26
27export function Point(x, y, round) {
28 // @property x: Number; The `x` coordinate of the point
29 this.x = (round ? Math.round(x) : x);
30 // @property y: Number; The `y` coordinate of the point
31 this.y = (round ? Math.round(y) : y);
32}
33
34var trunc = Math.trunc || function (v) {
35 return v > 0 ? Math.floor(v) : Math.ceil(v);
36};
37
38Point.prototype = {
39
40 // @method clone(): Point
41 // Returns a copy of the current point.
42 clone: function () {
43 return new Point(this.x, this.y);
44 },
45
46 // @method add(otherPoint: Point): Point
47 // Returns the result of addition of the current and the given points.
48 add: function (point) {
49 // non-destructive, returns a new point
50 return this.clone()._add(toPoint(point));
51 },
52
53 _add: function (point) {
54 // destructive, used directly for performance in situations where it's safe to modify existing point
55 this.x += point.x;
56 this.y += point.y;
57 return this;
58 },
59
60 // @method subtract(otherPoint: Point): Point
61 // Returns the result of subtraction of the given point from the current.
62 subtract: function (point) {
63 return this.clone()._subtract(toPoint(point));
64 },
65
66 _subtract: function (point) {
67 this.x -= point.x;
68 this.y -= point.y;
69 return this;
70 },
71
72 // @method divideBy(num: Number): Point
73 // Returns the result of division of the current point by the given number.
74 divideBy: function (num) {
75 return this.clone()._divideBy(num);
76 },
77
78 _divideBy: function (num) {
79 this.x /= num;
80 this.y /= num;
81 return this;
82 },
83
84 // @method multiplyBy(num: Number): Point
85 // Returns the result of multiplication of the current point by the given number.
86 multiplyBy: function (num) {
87 return this.clone()._multiplyBy(num);
88 },
89
90 _multiplyBy: function (num) {
91 this.x *= num;
92 this.y *= num;
93 return this;
94 },
95
96 // @method scaleBy(scale: Point): Point
97 // Multiply each coordinate of the current point by each coordinate of
98 // `scale`. In linear algebra terms, multiply the point by the
99 // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)
100 // defined by `scale`.
101 scaleBy: function (point) {
102 return new Point(this.x * point.x, this.y * point.y);
103 },
104
105 // @method unscaleBy(scale: Point): Point
106 // Inverse of `scaleBy`. Divide each coordinate of the current point by
107 // each coordinate of `scale`.
108 unscaleBy: function (point) {
109 return new Point(this.x / point.x, this.y / point.y);
110 },
111
112 // @method round(): Point
113 // Returns a copy of the current point with rounded coordinates.
114 round: function () {
115 return this.clone()._round();
116 },
117
118 _round: function () {
119 this.x = Math.round(this.x);
120 this.y = Math.round(this.y);
121 return this;
122 },
123
124 // @method floor(): Point
125 // Returns a copy of the current point with floored coordinates (rounded down).
126 floor: function () {
127 return this.clone()._floor();
128 },
129
130 _floor: function () {
131 this.x = Math.floor(this.x);
132 this.y = Math.floor(this.y);
133 return this;
134 },
135
136 // @method ceil(): Point
137 // Returns a copy of the current point with ceiled coordinates (rounded up).
138 ceil: function () {
139 return this.clone()._ceil();
140 },
141
142 _ceil: function () {
143 this.x = Math.ceil(this.x);
144 this.y = Math.ceil(this.y);
145 return this;
146 },
147
148 // @method trunc(): Point
149 // Returns a copy of the current point with truncated coordinates (rounded towards zero).
150 trunc: function () {
151 return this.clone()._trunc();
152 },
153
154 _trunc: function () {
155 this.x = trunc(this.x);
156 this.y = trunc(this.y);
157 return this;
158 },
159
160 // @method distanceTo(otherPoint: Point): Number
161 // Returns the cartesian distance between the current and the given points.
162 distanceTo: function (point) {
163 point = toPoint(point);
164
165 var x = point.x - this.x,
166 y = point.y - this.y;
167
168 return Math.sqrt(x * x + y * y);
169 },
170
171 // @method equals(otherPoint: Point): Boolean
172 // Returns `true` if the given point has the same coordinates.
173 equals: function (point) {
174 point = toPoint(point);
175
176 return point.x === this.x &&
177 point.y === this.y;
178 },
179
180 // @method contains(otherPoint: Point): Boolean
181 // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).
182 contains: function (point) {
183 point = toPoint(point);
184
185 return Math.abs(point.x) <= Math.abs(this.x) &&
186 Math.abs(point.y) <= Math.abs(this.y);
187 },
188
189 // @method toString(): String
190 // Returns a string representation of the point for debugging purposes.
191 toString: function () {
192 return 'Point(' +
193 formatNum(this.x) + ', ' +
194 formatNum(this.y) + ')';
195 }
196};
197
198// @factory L.point(x: Number, y: Number, round?: Boolean)
199// Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.
200
201// @alternative
202// @factory L.point(coords: Number[])
203// Expects an array of the form `[x, y]` instead.
204
205// @alternative
206// @factory L.point(coords: Object)
207// Expects a plain object of the form `{x: Number, y: Number}` instead.
208export function toPoint(x, y, round) {
209 if (x instanceof Point) {
210 return x;
211 }
212 if (isArray(x)) {
213 return new Point(x[0], x[1]);
214 }
215 if (x === undefined || x === null) {
216 return x;
217 }
218 if (typeof x === 'object' && 'x' in x && 'y' in x) {
219 return new Point(x.x, x.y);
220 }
221 return new Point(x, y, round);
222}