@maptiler/sdk 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -0
- package/dist/maptiler-sdk.css +1 -1
- package/dist/maptiler-sdk.d.ts +190 -241
- package/dist/maptiler-sdk.min.mjs +3 -3
- package/dist/maptiler-sdk.mjs +487 -460
- package/dist/maptiler-sdk.mjs.map +1 -1
- package/package.json +3 -3
- package/readme.md +211 -6
- package/CHANGELOG.md +0 -157
- package/colorramp.md +0 -93
- package/dist/maptiler-sdk.umd.js +0 -6997
- package/dist/maptiler-sdk.umd.js.map +0 -1
- package/dist/maptiler-sdk.umd.min.js +0 -582
- package/src/AttributionControl.ts +0 -13
- package/src/CanvasSource.ts +0 -13
- package/src/FullscreenControl.ts +0 -13
- package/src/GeoJSONSource.ts +0 -13
- package/src/GeolocateControl.ts +0 -13
- package/src/ImageSource.ts +0 -13
- package/src/LogoControl.ts +0 -13
- package/src/Map.ts +0 -1328
- package/src/MaptilerGeolocateControl.ts +0 -207
- package/src/MaptilerLogoControl.ts +0 -58
- package/src/MaptilerNavigationControl.ts +0 -69
- package/src/MaptilerTerrainControl.ts +0 -72
- package/src/Marker.ts +0 -13
- package/src/Minimap.ts +0 -373
- package/src/NavigationControl.ts +0 -13
- package/src/Point.ts +0 -334
- package/src/Popup.ts +0 -13
- package/src/RasterDEMTileSource.ts +0 -13
- package/src/RasterTileSource.ts +0 -13
- package/src/ScaleControl.ts +0 -13
- package/src/Style.ts +0 -13
- package/src/TerrainControl.ts +0 -13
- package/src/VectorTileSource.ts +0 -13
- package/src/VideoSource.ts +0 -13
- package/src/colorramp.ts +0 -1216
- package/src/config.ts +0 -96
- package/src/converters/index.ts +0 -1
- package/src/converters/xml.ts +0 -681
- package/src/defaults.ts +0 -20
- package/src/helpers/index.ts +0 -27
- package/src/helpers/stylehelper.ts +0 -395
- package/src/helpers/vectorlayerhelpers.ts +0 -1511
- package/src/index.ts +0 -242
- package/src/language.ts +0 -183
- package/src/mapstyle.ts +0 -46
- package/src/style/style_template.css +0 -146
- package/src/style/svg/v6-compass.svg +0 -12
- package/src/style/svg/v6-fullscreen-off.svg +0 -7
- package/src/style/svg/v6-fullscreen.svg +0 -7
- package/src/style/svg/v6-geolocate-active-error.svg +0 -10
- package/src/style/svg/v6-geolocate-active.svg +0 -7
- package/src/style/svg/v6-geolocate-background.svg +0 -8
- package/src/style/svg/v6-geolocate-disabled.svg +0 -10
- package/src/style/svg/v6-geolocate.svg +0 -7
- package/src/style/svg/v6-terrain-on.svg +0 -7
- package/src/style/svg/v6-terrain.svg +0 -7
- package/src/style/svg/v6-zoom-minus.svg +0 -7
- package/src/style/svg/v6-zoom-plus.svg +0 -7
- package/src/tools.ts +0 -171
- package/src/unit.ts +0 -1
package/src/Minimap.ts
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is an extension adds support for adding a minimap to one of the map's control containers.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { Map } from "./Map";
|
|
6
|
-
import { DOMcreate, DOMremove } from "./tools";
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
ControlPosition,
|
|
10
|
-
CustomLayerInterface,
|
|
11
|
-
FillLayerSpecification,
|
|
12
|
-
FilterSpecification,
|
|
13
|
-
GeoJSONSource,
|
|
14
|
-
IControl,
|
|
15
|
-
LayerSpecification,
|
|
16
|
-
LineLayerSpecification,
|
|
17
|
-
SourceSpecification,
|
|
18
|
-
StyleOptions,
|
|
19
|
-
StyleSetterOptions,
|
|
20
|
-
StyleSpecification,
|
|
21
|
-
StyleSwapOptions,
|
|
22
|
-
} from "maplibre-gl";
|
|
23
|
-
import type { MapOptions } from "./Map";
|
|
24
|
-
import type { MapStyleVariant, ReferenceMapStyle } from "@maptiler/client";
|
|
25
|
-
|
|
26
|
-
export interface ParentRect {
|
|
27
|
-
lineLayout: LineLayerSpecification["layout"];
|
|
28
|
-
linePaint: LineLayerSpecification["paint"];
|
|
29
|
-
fillPaint: FillLayerSpecification["paint"];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface MinimapOptionsInput {
|
|
33
|
-
/**
|
|
34
|
-
* Style of the map. Can be:
|
|
35
|
-
* - a full style URL (possibly with API key)
|
|
36
|
-
* - a shorthand with only the MapTIler style name (eg. `"streets-v2"`)
|
|
37
|
-
* - a longer form with the prefix `"maptiler://"` (eg. `"maptiler://streets-v2"`)
|
|
38
|
-
*/
|
|
39
|
-
style?: ReferenceMapStyle | MapStyleVariant | StyleSpecification | string;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Set the zoom difference between the parent and the minimap
|
|
43
|
-
* If the parent is zoomed to 10 and the minimap is zoomed to 8, the zoomAdjust should be 2
|
|
44
|
-
* Default: -4
|
|
45
|
-
*/
|
|
46
|
-
zoomAdjust?: number;
|
|
47
|
-
|
|
48
|
-
/** Set a zoom of the minimap and don't allow any future changes */
|
|
49
|
-
lockZoom?: number;
|
|
50
|
-
|
|
51
|
-
/** Adjust the pitch only if the user requests */
|
|
52
|
-
pitchAdjust?: boolean;
|
|
53
|
-
|
|
54
|
-
/** Set CSS properties of the container using object key-values */
|
|
55
|
-
containerStyle?: Record<string, string>;
|
|
56
|
-
|
|
57
|
-
/** Set the position of the minimap at either "top-left", "top-right", "bottom-left", or "bottom-right" */
|
|
58
|
-
position?: ControlPosition;
|
|
59
|
-
|
|
60
|
-
/** Set the parentRect fill and/or line options */
|
|
61
|
-
parentRect?: ParentRect;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface MinimapOptions extends MapOptions {
|
|
65
|
-
zoomAdjust: number;
|
|
66
|
-
pitchAdjust: boolean;
|
|
67
|
-
containerStyle: Record<string, string>;
|
|
68
|
-
parentRect?: ParentRect;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export default class Minimap implements IControl {
|
|
72
|
-
#options: MinimapOptions;
|
|
73
|
-
map!: Map;
|
|
74
|
-
#parentMap!: Map;
|
|
75
|
-
#container!: HTMLElement;
|
|
76
|
-
#canvasContainer!: HTMLElement;
|
|
77
|
-
#parentRect?: GeoJSON.Feature<GeoJSON.Polygon>;
|
|
78
|
-
#differentStyle = false;
|
|
79
|
-
#desync?: () => void;
|
|
80
|
-
constructor(options: MinimapOptionsInput, mapOptions: MapOptions) {
|
|
81
|
-
// check if the style is different
|
|
82
|
-
if (options.style !== undefined) this.#differentStyle = true;
|
|
83
|
-
// set options
|
|
84
|
-
this.#options = {
|
|
85
|
-
// set defaults
|
|
86
|
-
zoomAdjust: -4,
|
|
87
|
-
position: "top-right",
|
|
88
|
-
// inherit map options
|
|
89
|
-
...mapOptions,
|
|
90
|
-
// override any lingering control options
|
|
91
|
-
forceNoAttributionControl: true,
|
|
92
|
-
attributionControl: false,
|
|
93
|
-
navigationControl: false,
|
|
94
|
-
geolocateControl: false,
|
|
95
|
-
maptilerLogo: false,
|
|
96
|
-
minimap: false,
|
|
97
|
-
hash: false,
|
|
98
|
-
pitchAdjust: false,
|
|
99
|
-
// override map options with new user defined minimap options
|
|
100
|
-
...options,
|
|
101
|
-
containerStyle: {
|
|
102
|
-
border: "1px solid #000",
|
|
103
|
-
width: "400px",
|
|
104
|
-
height: "300px",
|
|
105
|
-
...(options.containerStyle ?? {}),
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
if (options.lockZoom !== undefined) {
|
|
109
|
-
this.#options.minZoom = options.lockZoom;
|
|
110
|
-
this.#options.maxZoom = options.lockZoom;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
setStyle(
|
|
115
|
-
style:
|
|
116
|
-
| null
|
|
117
|
-
| ReferenceMapStyle
|
|
118
|
-
| MapStyleVariant
|
|
119
|
-
| StyleSpecification
|
|
120
|
-
| string,
|
|
121
|
-
options?: StyleSwapOptions & StyleOptions,
|
|
122
|
-
): void {
|
|
123
|
-
if (!this.#differentStyle) this.map.setStyle(style, options);
|
|
124
|
-
this.#setParentBounds();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
addLayer(
|
|
128
|
-
layer:
|
|
129
|
-
| (LayerSpecification & {
|
|
130
|
-
source?: string | SourceSpecification;
|
|
131
|
-
})
|
|
132
|
-
| CustomLayerInterface,
|
|
133
|
-
beforeId?: string,
|
|
134
|
-
): Map {
|
|
135
|
-
if (!this.#differentStyle) this.map.addLayer(layer, beforeId);
|
|
136
|
-
this.#setParentBounds();
|
|
137
|
-
return this.map;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
moveLayer(id: string, beforeId?: string): Map {
|
|
141
|
-
if (!this.#differentStyle) this.map.moveLayer(id, beforeId);
|
|
142
|
-
this.#setParentBounds();
|
|
143
|
-
return this.map;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
removeLayer(id: string): this {
|
|
147
|
-
if (!this.#differentStyle) this.map.removeLayer(id);
|
|
148
|
-
this.#setParentBounds();
|
|
149
|
-
return this;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
setLayerZoomRange(layerId: string, minzoom: number, maxzoom: number): this {
|
|
153
|
-
if (!this.#differentStyle)
|
|
154
|
-
this.map.setLayerZoomRange(layerId, minzoom, maxzoom);
|
|
155
|
-
this.#setParentBounds();
|
|
156
|
-
return this;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
setFilter(
|
|
160
|
-
layerId: string,
|
|
161
|
-
filter?: FilterSpecification | null,
|
|
162
|
-
options?: StyleSetterOptions,
|
|
163
|
-
): this {
|
|
164
|
-
if (!this.#differentStyle) this.map.setFilter(layerId, filter, options);
|
|
165
|
-
this.#setParentBounds();
|
|
166
|
-
return this;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
setPaintProperty(
|
|
170
|
-
layerId: string,
|
|
171
|
-
name: string,
|
|
172
|
-
// maplibre controlled types
|
|
173
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
|
-
value: any,
|
|
175
|
-
options?: StyleSetterOptions,
|
|
176
|
-
): this {
|
|
177
|
-
if (!this.#differentStyle)
|
|
178
|
-
this.map.setPaintProperty(layerId, name, value, options);
|
|
179
|
-
this.#setParentBounds();
|
|
180
|
-
return this;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
setLayoutProperty(
|
|
184
|
-
layerId: string,
|
|
185
|
-
name: string,
|
|
186
|
-
// maplibre controlled types
|
|
187
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
188
|
-
value: any,
|
|
189
|
-
options?: StyleSetterOptions,
|
|
190
|
-
): this {
|
|
191
|
-
if (!this.#differentStyle)
|
|
192
|
-
this.map.setLayoutProperty(layerId, name, value, options);
|
|
193
|
-
this.#setParentBounds();
|
|
194
|
-
return this;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
setGlyphs(glyphsUrl: string | null, options?: StyleSetterOptions): this {
|
|
198
|
-
if (!this.#differentStyle) this.map.setGlyphs(glyphsUrl, options);
|
|
199
|
-
this.#setParentBounds();
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
onAdd(parentMap: Map): HTMLElement {
|
|
204
|
-
this.#parentMap = parentMap;
|
|
205
|
-
//prep the container
|
|
206
|
-
this.#container = DOMcreate("div", "maplibregl-ctrl maplibregl-ctrl-group");
|
|
207
|
-
// adjust styling
|
|
208
|
-
for (const [key, value] of Object.entries(this.#options.containerStyle)) {
|
|
209
|
-
this.#container.style.setProperty(key, value);
|
|
210
|
-
}
|
|
211
|
-
this.#options.container = this.#container;
|
|
212
|
-
this.#options.zoom = parentMap.getZoom() + this.#options.zoomAdjust ?? -4;
|
|
213
|
-
this.map = new Map(this.#options);
|
|
214
|
-
|
|
215
|
-
// NOTE: For some reason the DOM doesn't properly update it's size in time
|
|
216
|
-
// for the minimap to convey it's size to the canvas.
|
|
217
|
-
this.map.once("style.load", () => {
|
|
218
|
-
this.map.resize();
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// set options
|
|
222
|
-
this.map.once("load", () => {
|
|
223
|
-
this.#addParentRect(this.#options.parentRect);
|
|
224
|
-
this.#desync = this.#syncMaps();
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
return this.#container;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
onRemove(): void {
|
|
231
|
-
this.#desync?.();
|
|
232
|
-
DOMremove(this.#container);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
#addParentRect(rect?: ParentRect): void {
|
|
236
|
-
if (
|
|
237
|
-
rect === undefined ||
|
|
238
|
-
(rect.linePaint === undefined && rect.fillPaint === undefined)
|
|
239
|
-
) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
this.#parentRect = {
|
|
243
|
-
type: "Feature",
|
|
244
|
-
properties: {
|
|
245
|
-
name: "parentRect",
|
|
246
|
-
},
|
|
247
|
-
geometry: {
|
|
248
|
-
type: "Polygon",
|
|
249
|
-
coordinates: [[[], [], [], [], []]],
|
|
250
|
-
},
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
this.map.addSource("parentRect", {
|
|
254
|
-
type: "geojson",
|
|
255
|
-
data: this.#parentRect,
|
|
256
|
-
});
|
|
257
|
-
if (rect.lineLayout !== undefined || rect.linePaint !== undefined) {
|
|
258
|
-
this.map.addLayer({
|
|
259
|
-
id: "parentRectOutline",
|
|
260
|
-
type: "line",
|
|
261
|
-
source: "parentRect",
|
|
262
|
-
layout: {
|
|
263
|
-
...rect.lineLayout,
|
|
264
|
-
},
|
|
265
|
-
paint: {
|
|
266
|
-
"line-color": "#FFF",
|
|
267
|
-
"line-width": 1,
|
|
268
|
-
"line-opacity": 0.85,
|
|
269
|
-
...rect.linePaint,
|
|
270
|
-
},
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
if (rect.fillPaint !== undefined) {
|
|
274
|
-
this.map.addLayer({
|
|
275
|
-
id: "parentRectFill",
|
|
276
|
-
type: "fill",
|
|
277
|
-
source: "parentRect",
|
|
278
|
-
layout: {},
|
|
279
|
-
paint: {
|
|
280
|
-
"fill-color": "#08F",
|
|
281
|
-
"fill-opacity": 0.135,
|
|
282
|
-
...rect.fillPaint,
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
this.#setParentBounds();
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
#setParentBounds() {
|
|
291
|
-
if (this.#parentRect === undefined) return;
|
|
292
|
-
|
|
293
|
-
const { devicePixelRatio } = window;
|
|
294
|
-
const canvas = this.#parentMap.getCanvas();
|
|
295
|
-
const width = canvas.width / devicePixelRatio;
|
|
296
|
-
const height = canvas.height / devicePixelRatio;
|
|
297
|
-
|
|
298
|
-
// Get coordinates for all four corners
|
|
299
|
-
const unproject = this.#parentMap.unproject.bind(this.#parentMap);
|
|
300
|
-
const northWest = unproject([0, 0]);
|
|
301
|
-
const northEast = unproject([width, 0]);
|
|
302
|
-
const southWest = unproject([0, height]);
|
|
303
|
-
const southEast = unproject([width, height]);
|
|
304
|
-
|
|
305
|
-
this.#parentRect.geometry.coordinates = [
|
|
306
|
-
[
|
|
307
|
-
southWest.toArray(),
|
|
308
|
-
southEast.toArray(),
|
|
309
|
-
northEast.toArray(),
|
|
310
|
-
northWest.toArray(),
|
|
311
|
-
southWest.toArray(),
|
|
312
|
-
],
|
|
313
|
-
];
|
|
314
|
-
|
|
315
|
-
const source = this.map.getSource("parentRect") as GeoJSONSource;
|
|
316
|
-
source.setData(this.#parentRect);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
#syncMaps(): () => void {
|
|
320
|
-
const { pitchAdjust } = this.#options;
|
|
321
|
-
// syncing callbacks
|
|
322
|
-
const parentCallback = () => {
|
|
323
|
-
sync("parent");
|
|
324
|
-
};
|
|
325
|
-
const minimapCallback = () => {
|
|
326
|
-
sync("minimap");
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
// on off functions
|
|
330
|
-
const on = () => {
|
|
331
|
-
this.#parentMap.on("move", parentCallback);
|
|
332
|
-
this.map.on("move", minimapCallback);
|
|
333
|
-
};
|
|
334
|
-
const off = () => {
|
|
335
|
-
this.#parentMap.off("move", parentCallback);
|
|
336
|
-
this.map.off("move", minimapCallback);
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
// When one map moves, we turn off the movement listeners
|
|
340
|
-
// on all the maps, move it, then turn the listeners on again
|
|
341
|
-
const sync = (which: "parent" | "minimap") => {
|
|
342
|
-
// OFF
|
|
343
|
-
off();
|
|
344
|
-
|
|
345
|
-
// MOVE
|
|
346
|
-
const from = which === "parent" ? this.#parentMap : this.map;
|
|
347
|
-
const to = which === "parent" ? this.map : this.#parentMap;
|
|
348
|
-
const center = from.getCenter();
|
|
349
|
-
const zoom =
|
|
350
|
-
from.getZoom() +
|
|
351
|
-
(this.#options.zoomAdjust ?? -4) * (which === "parent" ? 1 : -1);
|
|
352
|
-
const bearing = from.getBearing();
|
|
353
|
-
const pitch = from.getPitch();
|
|
354
|
-
to.jumpTo({
|
|
355
|
-
center,
|
|
356
|
-
zoom,
|
|
357
|
-
bearing,
|
|
358
|
-
pitch: pitchAdjust ? pitch : 0,
|
|
359
|
-
});
|
|
360
|
-
// update parent rect
|
|
361
|
-
this.#setParentBounds();
|
|
362
|
-
|
|
363
|
-
// ON
|
|
364
|
-
on();
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
on();
|
|
368
|
-
// return a desync function
|
|
369
|
-
return () => {
|
|
370
|
-
off();
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
}
|
package/src/NavigationControl.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is an extension of MapLibre NavigationControl to make it fully type compatible with the SDK
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import maplibregl from "maplibre-gl";
|
|
6
|
-
import type { Map as MapMLGL } from "maplibre-gl";
|
|
7
|
-
import { Map } from "./Map";
|
|
8
|
-
|
|
9
|
-
export class NavigationControl extends maplibregl.NavigationControl {
|
|
10
|
-
onAdd(map: Map | MapMLGL) {
|
|
11
|
-
return super.onAdd(map as MapMLGL);
|
|
12
|
-
}
|
|
13
|
-
}
|
package/src/Point.ts
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is TypeScript rewrite of the Point class to use instead of the version imported in MapLibre.
|
|
3
|
-
* It also uses a class instead of prototypes.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Row major 2x2 matrix
|
|
8
|
-
*/
|
|
9
|
-
export type Matrix2 = [number, number, number, number];
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* a point
|
|
13
|
-
*/
|
|
14
|
-
export class Point {
|
|
15
|
-
public x: number;
|
|
16
|
-
public y: number;
|
|
17
|
-
|
|
18
|
-
constructor(x: number, y: number) {
|
|
19
|
-
this.x = x;
|
|
20
|
-
this.y = y;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
private _matMult(m: Matrix2): Point {
|
|
24
|
-
const x = m[0] * this.x + m[1] * this.y;
|
|
25
|
-
const y = m[2] * this.x + m[3] * this.y;
|
|
26
|
-
this.x = x;
|
|
27
|
-
this.y = y;
|
|
28
|
-
return this;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private _add(p: Point): Point {
|
|
32
|
-
this.x += p.x;
|
|
33
|
-
this.y += p.y;
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private _sub(p: Point): Point {
|
|
38
|
-
this.x -= p.x;
|
|
39
|
-
this.y -= p.y;
|
|
40
|
-
return this;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
private _mult(k: number): Point {
|
|
44
|
-
this.x *= k;
|
|
45
|
-
this.y *= k;
|
|
46
|
-
return this;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private _div(k: number): Point {
|
|
50
|
-
this.x /= k;
|
|
51
|
-
this.y /= k;
|
|
52
|
-
return this;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private _multByPoint(p: Point): Point {
|
|
56
|
-
this.x *= p.x;
|
|
57
|
-
this.y *= p.y;
|
|
58
|
-
return this;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private _divByPoint(p: Point): Point {
|
|
62
|
-
this.x /= p.x;
|
|
63
|
-
this.y /= p.y;
|
|
64
|
-
return this;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private _unit(): Point {
|
|
68
|
-
this._div(this.mag());
|
|
69
|
-
return this;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private _perp(): Point {
|
|
73
|
-
const y = this.y;
|
|
74
|
-
this.y = this.x;
|
|
75
|
-
this.x = -y;
|
|
76
|
-
return this;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private _rotate(angle: number): Point {
|
|
80
|
-
const cos = Math.cos(angle);
|
|
81
|
-
const sin = Math.sin(angle);
|
|
82
|
-
const x = cos * this.x - sin * this.y;
|
|
83
|
-
const y = sin * this.x + cos * this.y;
|
|
84
|
-
this.x = x;
|
|
85
|
-
this.y = y;
|
|
86
|
-
return this;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private _rotateAround(angle: number, p: Point): Point {
|
|
90
|
-
const cos = Math.cos(angle);
|
|
91
|
-
const sin = Math.sin(angle);
|
|
92
|
-
const x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y);
|
|
93
|
-
const y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
|
|
94
|
-
this.x = x;
|
|
95
|
-
this.y = y;
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private _round(): Point {
|
|
100
|
-
this.x = Math.round(this.x);
|
|
101
|
-
this.y = Math.round(this.y);
|
|
102
|
-
return this;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Clone this point, returning a new point that can be modified
|
|
107
|
-
* without affecting the old one.
|
|
108
|
-
* @return {Point} the clone
|
|
109
|
-
*/
|
|
110
|
-
clone(): Point {
|
|
111
|
-
return new Point(this.x, this.y);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Add this point's x & y coordinates to another point,
|
|
116
|
-
* yielding a new point.
|
|
117
|
-
* @param {Point} p the other point
|
|
118
|
-
* @return {Point} output point
|
|
119
|
-
*/
|
|
120
|
-
add(p: Point): Point {
|
|
121
|
-
return this.clone()._add(p);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Subtract this point's x & y coordinates to from point,
|
|
126
|
-
* yielding a new point.
|
|
127
|
-
* @param {Point} p the other point
|
|
128
|
-
* @return {Point} output point
|
|
129
|
-
*/
|
|
130
|
-
sub(p: Point): Point {
|
|
131
|
-
return this.clone()._sub(p);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Multiply this point's x & y coordinates by point,
|
|
136
|
-
* yielding a new point.
|
|
137
|
-
* @param {Point} p the other point
|
|
138
|
-
* @return {Point} output point
|
|
139
|
-
*/
|
|
140
|
-
multByPoint(p: Point): Point {
|
|
141
|
-
return this.clone()._multByPoint(p);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Divide this point's x & y coordinates by point,
|
|
146
|
-
* yielding a new point.
|
|
147
|
-
* @param {Point} p the other point
|
|
148
|
-
* @return {Point} output point
|
|
149
|
-
*/
|
|
150
|
-
divByPoint(p: Point): Point {
|
|
151
|
-
return this.clone()._divByPoint(p);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Multiply this point's x & y coordinates by a factor,
|
|
156
|
-
* yielding a new point.
|
|
157
|
-
* @param {Number} k factor
|
|
158
|
-
* @return {Point} output point
|
|
159
|
-
*/
|
|
160
|
-
mult(k: number): Point {
|
|
161
|
-
return this.clone()._mult(k);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Divide this point's x & y coordinates by a factor,
|
|
166
|
-
* yielding a new point.
|
|
167
|
-
* @param {Point} k factor
|
|
168
|
-
* @return {Point} output point
|
|
169
|
-
*/
|
|
170
|
-
div(k: number): Point {
|
|
171
|
-
return this.clone()._div(k);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Rotate this point around the 0, 0 origin by an angle a,
|
|
176
|
-
* given in radians
|
|
177
|
-
* @param {Number} a angle to rotate around, in radians
|
|
178
|
-
* @return {Point} output point
|
|
179
|
-
*/
|
|
180
|
-
rotate(a: number): Point {
|
|
181
|
-
return this.clone()._rotate(a);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Rotate this point around p point by an angle a,
|
|
186
|
-
* given in radians
|
|
187
|
-
* @param {Number} a angle to rotate around, in radians
|
|
188
|
-
* @param {Point} p Point to rotate around
|
|
189
|
-
* @return {Point} output point
|
|
190
|
-
*/
|
|
191
|
-
rotateAround(a: number, p: Point): Point {
|
|
192
|
-
return this.clone()._rotateAround(a, p);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Multiply this point by a 4x1 transformation matrix
|
|
197
|
-
* @param {Array<Number>} m transformation matrix
|
|
198
|
-
* @return {Point} output point
|
|
199
|
-
*/
|
|
200
|
-
matMult(m: Matrix2): Point {
|
|
201
|
-
return this.clone()._matMult(m);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Calculate this point but as a unit vector from 0, 0, meaning
|
|
206
|
-
* that the distance from the resulting point to the 0, 0
|
|
207
|
-
* coordinate will be equal to 1 and the angle from the resulting
|
|
208
|
-
* point to the 0, 0 coordinate will be the same as before.
|
|
209
|
-
* @return {Point} unit vector point
|
|
210
|
-
*/
|
|
211
|
-
unit(): Point {
|
|
212
|
-
return this.clone()._unit();
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Compute a perpendicular point, where the new y coordinate
|
|
217
|
-
* is the old x coordinate and the new x coordinate is the old y
|
|
218
|
-
* coordinate multiplied by -1
|
|
219
|
-
* @return {Point} perpendicular point
|
|
220
|
-
*/
|
|
221
|
-
perp(): Point {
|
|
222
|
-
return this.clone()._perp();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Return a version of this point with the x & y coordinates
|
|
227
|
-
* rounded to integers.
|
|
228
|
-
* @return {Point} rounded point
|
|
229
|
-
*/
|
|
230
|
-
round(): Point {
|
|
231
|
-
return this.clone()._round();
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Return the magnitude of this point: this is the Euclidean
|
|
236
|
-
* distance from the 0, 0 coordinate to this point's x and y
|
|
237
|
-
* coordinates.
|
|
238
|
-
* @return {Number} magnitude
|
|
239
|
-
*/
|
|
240
|
-
mag(): number {
|
|
241
|
-
return Math.sqrt(this.x * this.x + this.y * this.y);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Judge whether this point is equal to another point, returning
|
|
246
|
-
* true or false.
|
|
247
|
-
* @param {Point} other the other point
|
|
248
|
-
* @return {boolean} whether the points are equal
|
|
249
|
-
*/
|
|
250
|
-
equals(other: Point): boolean {
|
|
251
|
-
return this.x === other.x && this.y === other.y;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Calculate the distance from this point to another point
|
|
256
|
-
* @param {Point} p the other point
|
|
257
|
-
* @return {Number} distance
|
|
258
|
-
*/
|
|
259
|
-
dist(p: Point): number {
|
|
260
|
-
return Math.sqrt(this.distSqr(p));
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Calculate the distance from this point to another point,
|
|
265
|
-
* without the square root step. Useful if you're comparing
|
|
266
|
-
* relative distances.
|
|
267
|
-
* @param {Point} p the other point
|
|
268
|
-
* @return {Number} distance
|
|
269
|
-
*/
|
|
270
|
-
distSqr(p: Point): number {
|
|
271
|
-
const dx = p.x - this.x;
|
|
272
|
-
const dy = p.y - this.y;
|
|
273
|
-
return dx * dx + dy * dy;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Get the angle from the 0, 0 coordinate to this point, in radians
|
|
278
|
-
* coordinates.
|
|
279
|
-
* @return {Number} angle
|
|
280
|
-
*/
|
|
281
|
-
angle(): number {
|
|
282
|
-
return Math.atan2(this.y, this.x);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Get the angle from this point to another point, in radians
|
|
287
|
-
* @param {Point} b the other point
|
|
288
|
-
* @return {Number} angle
|
|
289
|
-
*/
|
|
290
|
-
angleTo(b: Point): number {
|
|
291
|
-
return Math.atan2(this.y - b.y, this.x - b.x);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Get the angle between this point and another point, in radians
|
|
296
|
-
* @param {Point} b the other point
|
|
297
|
-
* @return {Number} angle
|
|
298
|
-
*/
|
|
299
|
-
angleWith(b: Point): number {
|
|
300
|
-
return this.angleWithSep(b.x, b.y);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/*
|
|
304
|
-
* Find the angle of the two vectors, solving the formula for
|
|
305
|
-
* the cross product a x b = |a||b|sin(θ) for θ.
|
|
306
|
-
* @param {Number} x the x-coordinate
|
|
307
|
-
* @param {Number} y the y-coordinate
|
|
308
|
-
* @return {Number} the angle in radians
|
|
309
|
-
*/
|
|
310
|
-
angleWithSep(x: number, y: number): number {
|
|
311
|
-
return Math.atan2(this.x * y - this.y * x, this.x * x + this.y * y);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Construct a point from an array if necessary, otherwise if the input
|
|
316
|
-
* is already a Point, or an unknown type, return it unchanged
|
|
317
|
-
* @param {Array<number> | Point} a any kind of input value
|
|
318
|
-
* @return {Point} constructed point, or passed-through value.
|
|
319
|
-
* @example
|
|
320
|
-
* // this
|
|
321
|
-
* var point = Point.convert([0, 1]);
|
|
322
|
-
* // is equivalent to
|
|
323
|
-
* var point = new Point(0, 1);
|
|
324
|
-
*/
|
|
325
|
-
static convert(a: Point | Array<number>) {
|
|
326
|
-
if (a instanceof Point) {
|
|
327
|
-
return a;
|
|
328
|
-
}
|
|
329
|
-
if (Array.isArray(a)) {
|
|
330
|
-
return new Point(a[0], a[1]);
|
|
331
|
-
}
|
|
332
|
-
return a;
|
|
333
|
-
}
|
|
334
|
-
}
|