isard 1.7.0 → 1.9.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/CHANGELOG.md +53 -0
- package/dist/basemap/grid.js +2 -5
- package/dist/basemap/grid.js.map +1 -1
- package/dist/basemap/models/furniture.d.ts +12 -0
- package/dist/basemap/{furniture.js → models/furniture.js} +6 -8
- package/dist/basemap/models/furniture.js.map +1 -0
- package/dist/basemap/{meshes.js → models/meshes.js} +1 -1
- package/dist/basemap/models/meshes.js.map +1 -0
- package/dist/basemap/models/trees.d.ts +21 -0
- package/dist/basemap/{trees.js → models/trees.js} +4 -36
- package/dist/basemap/models/trees.js.map +1 -0
- package/dist/basemap/placed.d.ts +2 -0
- package/dist/basemap/placed.js +2 -0
- package/dist/basemap/placed.js.map +1 -1
- package/dist/basemap/pmtiles.js +4 -3
- package/dist/basemap/pmtiles.js.map +1 -1
- package/dist/basemap/pmtileslayer.d.ts +4 -4
- package/dist/basemap/pmtileslayer.js +2 -1
- package/dist/basemap/pmtileslayer.js.map +1 -1
- package/dist/basemap/resample.js +3 -2
- package/dist/basemap/resample.js.map +1 -1
- package/dist/basemap/terrain.d.ts +5 -0
- package/dist/basemap/terrain.js +6 -4
- package/dist/basemap/terrain.js.map +1 -1
- package/dist/basemap/vectortiles/context.d.ts +3 -2
- package/dist/basemap/vectortiles/context.js.map +1 -1
- package/dist/basemap/vectortiles/extrusions.js.map +1 -1
- package/dist/basemap/vectortiles/furniture.d.ts +3 -3
- package/dist/basemap/vectortiles/furniture.js +2 -1
- package/dist/basemap/vectortiles/furniture.js.map +1 -1
- package/dist/basemap/vectortiles/labels.js +2 -1
- package/dist/basemap/vectortiles/labels.js.map +1 -1
- package/dist/basemap/vectortiles/lamps.d.ts +3 -3
- package/dist/basemap/vectortiles/lamps.js +1 -1
- package/dist/basemap/vectortiles/lamps.js.map +1 -1
- package/dist/basemap/vectortiles/placed.d.ts +3 -2
- package/dist/basemap/vectortiles/placed.js +5 -10
- package/dist/basemap/vectortiles/placed.js.map +1 -1
- package/dist/basemap/vectortiles/street-wind.js +2 -2
- package/dist/basemap/vectortiles/street-wind.js.map +1 -1
- package/dist/basemap/vectortiles/style.js +7 -8
- package/dist/basemap/vectortiles/style.js.map +1 -1
- package/dist/basemap/vectortiles/tiles.d.ts +1 -3
- package/dist/basemap/vectortiles/tiles.js +1 -1
- package/dist/basemap/vectortiles/tiles.js.map +1 -1
- package/dist/basemap/vectortiles/trees.d.ts +4 -4
- package/dist/basemap/vectortiles/trees.js +2 -1
- package/dist/basemap/vectortiles/trees.js.map +1 -1
- package/dist/basemap/vectortiles/vectors.d.ts +2 -3
- package/dist/basemap/vectortiles/vectors.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +6 -5
- package/dist/basemap/vectortiles.js +4 -3
- package/dist/basemap/vectortiles.js.map +1 -1
- package/dist/basemap/wmts.js +3 -4
- package/dist/basemap/wmts.js.map +1 -1
- package/dist/basemap/{trees.d.ts → woods.d.ts} +2 -19
- package/dist/basemap/woods.js +38 -0
- package/dist/basemap/woods.js.map +1 -0
- package/dist/basemap/workerpool.d.ts +1 -1
- package/dist/basemap/workerpool.js +3 -3
- package/dist/basemap/workerpool.js.map +1 -1
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +23 -22
- package/dist/bind/layers.d.ts +10 -3
- package/dist/bind/layers.js +11 -4
- package/dist/bind/layers.js.map +1 -1
- package/dist/data/collada.js +4 -4
- package/dist/data/collada.js.map +1 -1
- package/dist/data/ifc.js +6 -11
- package/dist/data/ifc.js.map +1 -1
- package/dist/decoder.worker.js +5 -5
- package/dist/decoder.worker.js.map +7 -6
- package/dist/decoding/decoders.js.map +1 -0
- package/dist/{engine → decoding}/loader.js +2 -2
- package/dist/decoding/loader.js.map +1 -0
- package/dist/{engine → decoding}/protocol.d.ts +1 -1
- package/dist/decoding/protocol.js.map +1 -0
- package/dist/engine-loader.d.ts +1 -1
- package/dist/engine-loader.js +3 -2
- package/dist/engine-loader.js.map +1 -1
- package/dist/geoplateforme.d.ts +4 -3
- package/dist/geoplateforme.js +8 -10
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +16 -8
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_grid_bg.wasm +0 -0
- package/dist/isard_tess_bg.wasm +0 -0
- package/dist/layers/custom.d.ts +56 -0
- package/dist/layers/custom.js +93 -0
- package/dist/layers/custom.js.map +1 -0
- package/dist/layers/extrusions.d.ts +4 -2
- package/dist/layers/extrusions.js +2 -1
- package/dist/layers/extrusions.js.map +1 -1
- package/dist/layers/features.d.ts +3 -14
- package/dist/layers/features.js +4 -25
- package/dist/layers/features.js.map +1 -1
- package/dist/layers/flow.d.ts +3 -3
- package/dist/layers/flow.js +3 -4
- package/dist/layers/flow.js.map +1 -1
- package/dist/layers/glyphs.js +5 -3
- package/dist/layers/glyphs.js.map +1 -1
- package/dist/layers/ground.d.ts +57 -0
- package/dist/layers/ground.js +78 -0
- package/dist/layers/ground.js.map +1 -0
- package/dist/layers/icons.js +8 -6
- package/dist/layers/icons.js.map +1 -1
- package/dist/layers/layers.d.ts +2 -199
- package/dist/layers/layers.js +2 -469
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/models.d.ts +48 -0
- package/dist/layers/models.js +111 -0
- package/dist/layers/models.js.map +1 -0
- package/dist/layers/network.d.ts +26 -0
- package/dist/layers/network.js +127 -0
- package/dist/layers/network.js.map +1 -0
- package/dist/layers/panoramas.d.ts +2 -11
- package/dist/layers/panoramas.js +19 -9
- package/dist/layers/panoramas.js.map +1 -1
- package/dist/layers/photos.d.ts +4 -7
- package/dist/layers/photos.js +3 -4
- package/dist/layers/photos.js.map +1 -1
- package/dist/layers/pointclouds.d.ts +3 -2
- package/dist/layers/pointclouds.js +3 -3
- package/dist/layers/pointclouds.js.map +1 -1
- package/dist/layers/raster.d.ts +9 -0
- package/dist/layers/raster.js +24 -0
- package/dist/layers/raster.js.map +1 -0
- package/dist/layers/symbols.d.ts +2 -2
- package/dist/layers/symbols.js +2 -1
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/tiles3d.d.ts +15 -0
- package/dist/layers/tiles3d.js +55 -0
- package/dist/layers/tiles3d.js.map +1 -0
- package/dist/layers/trees.d.ts +5 -7
- package/dist/layers/trees.js +2 -1
- package/dist/layers/trees.js.map +1 -1
- package/dist/layers/vectors.js.map +1 -1
- package/dist/map/basemap-layers.js +1 -1
- package/dist/map/basemap-layers.js.map +1 -1
- package/dist/map/engine-settings.d.ts +1 -1
- package/dist/map/engine-settings.js +1 -1
- package/dist/map/engine-settings.js.map +1 -1
- package/dist/map/engines.js.map +1 -1
- package/dist/map/layer-spec.d.ts +7 -13
- package/dist/map/layer-spec.js.map +1 -1
- package/dist/map/workers.js +3 -4
- package/dist/map/workers.js.map +1 -1
- package/dist/map.d.ts +15 -58
- package/dist/map.js +39 -52
- package/dist/map.js.map +1 -1
- package/dist/panoramax.d.ts +15 -2
- package/dist/panoramax.js +38 -21
- package/dist/panoramax.js.map +1 -1
- package/dist/react/CustomLayer.d.ts +1 -1
- package/dist/react/CustomLayer.js +5 -4
- package/dist/react/CustomLayer.js.map +1 -1
- package/dist/react/Layer.d.ts +6 -2
- package/dist/react/Layer.js +6 -5
- package/dist/react/Layer.js.map +1 -1
- package/dist/react/VectorGeometry.js +5 -4
- package/dist/react/VectorGeometry.js.map +1 -1
- package/dist/react/VectorTiles.d.ts +2 -2
- package/dist/react/VectorTiles.js +1 -1
- package/dist/react/VectorTiles.js.map +1 -1
- package/dist/react/context.d.ts +3 -0
- package/dist/react/context.js +8 -1
- package/dist/react/context.js.map +1 -1
- package/dist/types.d.ts +14 -4
- package/dist/types.js.map +1 -1
- package/dist/ui/controls.js +2 -1
- package/dist/ui/controls.js.map +1 -1
- package/dist/ui/interaction.js +6 -5
- package/dist/ui/interaction.js.map +1 -1
- package/dist/ui/minimap.js +1 -1
- package/dist/ui/minimap.js.map +1 -1
- package/dist/ui/overlay.js +3 -3
- package/dist/ui/overlay.js.map +1 -1
- package/dist/ui/search.js +1 -1
- package/dist/ui/search.js.map +1 -1
- package/dist/util/animation.js +3 -2
- package/dist/util/animation.js.map +1 -1
- package/dist/util/color.d.ts +10 -0
- package/dist/util/color.js +29 -9
- package/dist/util/color.js.map +1 -1
- package/dist/util/fetch.d.ts +5 -0
- package/dist/util/fetch.js +11 -0
- package/dist/util/fetch.js.map +1 -0
- package/dist/util/geo.d.ts +5 -0
- package/dist/util/geo.js +8 -2
- package/dist/util/geo.js.map +1 -1
- package/dist/util/math.d.ts +3 -0
- package/dist/util/math.js +4 -0
- package/dist/util/math.js.map +1 -0
- package/dist/util/requests.js.map +1 -0
- package/dist/util/roofs.d.ts +0 -2
- package/dist/util/roofs.js +0 -3
- package/dist/util/roofs.js.map +1 -1
- package/dist/wasm/isard.js +1 -1
- package/dist/wasm/isard_core.js +1 -1
- package/dist/workers/basemap/geometry.d.ts +9 -19
- package/dist/workers/{basemap.worker.d.ts → basemap/protocol.d.ts} +29 -23
- package/dist/workers/basemap/street.d.ts +4 -2
- package/dist/workers/basemap/tiles.d.ts +1 -3
- package/dist/workers/basemap/trees.d.ts +2 -2
- package/package.json +1 -1
- package/dist/basemap/furniture.d.ts +0 -26
- package/dist/basemap/furniture.js.map +0 -1
- package/dist/basemap/meshes.js.map +0 -1
- package/dist/basemap/trees.js.map +0 -1
- package/dist/engine/decoders.js.map +0 -1
- package/dist/engine/loader.js.map +0 -1
- package/dist/engine/protocol.js.map +0 -1
- package/dist/engine/requests.js.map +0 -1
- package/dist/workers/basemap/furniture.d.ts +0 -13
- package/dist/workers/basemap/labels.d.ts +0 -24
- package/dist/workers/basemap/lamps.d.ts +0 -10
- package/dist/workers/basemap/raster.d.ts +0 -10
- package/dist/workers/basemap.worker.js +0 -221
- package/dist/workers/basemap.worker.js.map +0 -1
- /package/dist/basemap/{meshes.d.ts → models/meshes.d.ts} +0 -0
- /package/dist/{engine → decoding}/decoders.d.ts +0 -0
- /package/dist/{engine → decoding}/decoders.js +0 -0
- /package/dist/{engine → decoding}/loader.d.ts +0 -0
- /package/dist/{engine → decoding}/protocol.js +0 -0
- /package/dist/{engine → util}/requests.d.ts +0 -0
- /package/dist/{engine → util}/requests.js +0 -0
package/dist/ui/overlay.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","sourceRoot":"","sources":["../../src/ui/overlay.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DOM overlays tied to a position: markers and popups. The map places them all in one pass after each frame it draws\n * (camera moves, finer relief arriving), with a CSS transform from `map.project`: the browser only composites them,\n * nothing is laid out again.\n */\nimport type { GeoMap } from '../map.ts';\nimport type { LonLat, Point } from '../types.ts';\n\n/** Which part of the element sits on the position */\nexport type Anchor =\n | 'center'\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-left'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-right';\n\nconst ANCHOR_TRANSLATE: Record<Anchor, string> = {\n center: 'translate(-50%, -50%)',\n top: 'translate(-50%, 0)',\n bottom: 'translate(-50%, -100%)',\n left: 'translate(0, -50%)',\n right: 'translate(-100%, -50%)',\n 'top-left': 'translate(0, 0)',\n 'top-right': 'translate(-100%, 0)',\n 'bottom-left': 'translate(0, -100%)',\n 'bottom-right': 'translate(-100%, -100%)',\n};\n\n/** Where the anchor lies within the element, CSS percentages: the stem of a raised marker starts there */\nconst ANCHOR_POINT: Record<Anchor, [string, string]> = {\n center: ['50%', '50%'],\n top: ['50%', '0'],\n bottom: ['50%', '100%'],\n left: ['0', '50%'],\n right: ['100%', '50%'],\n 'top-left': ['0', '0'],\n 'top-right': ['100%', '0'],\n 'bottom-left': ['0', '100%'],\n 'bottom-right': ['100%', '100%'],\n};\n\n/** Overlays further than this out of the canvas (CSS pixels) are hidden: no part of them can show, and huge\n * transforms near the horizon would only cost the compositor */\nconst MARGIN = 500;\n/** A press on a draggable marker that moves less than this (CSS pixels) is a click */\nconst DRAG_TOLERANCE = 3;\n\n/** @internal What the map places after each frame */\nexport interface Positioned {\n /** Places the overlay for the current camera; `size` is the canvas size in CSS pixels */\n position(size: Point): void;\n}\n\n/** Typed listeners of an overlay */\nclass Emitter<E> {\n private readonly listeners: { [K in keyof E]?: Set<(event: E[K]) => void> } = {};\n\n on<K extends keyof E>(type: K, listener: (event: E[K]) => void): () => void {\n const set = this.listeners[type] ?? new Set();\n\n this.listeners[type] = set;\n set.add(listener);\n\n return () => set.delete(listener);\n }\n\n emit<K extends keyof E>(type: K, event: E[K]): void {\n this.listeners[type]?.forEach((listener) => {\n listener(event);\n });\n }\n}\n\n/** Moves `element` so that its anchor sits on `lonLat`, `height` metres above the ground, or hides it when the\n * position is out of sight; returns the screen point */\nconst place = (\n map: GeoMap,\n element: HTMLElement,\n lonLat: LonLat,\n height: number,\n anchor: Anchor,\n offset: Point,\n size: Point,\n): Point | undefined => {\n const point = map.project(lonLat, height);\n const visible =\n point !== undefined &&\n point[0] > -MARGIN &&\n point[0] < size[0] + MARGIN &&\n point[1] > -MARGIN &&\n point[1] < size[1] + MARGIN;\n\n if (!visible) {\n element.style.display = 'none';\n\n return undefined;\n }\n element.style.display = '';\n\n // Whole pixels: a fractional translation blurs text and icons\n const x = Math.round(point[0] + offset[0]);\n const y = Math.round(point[1] + offset[1]);\n\n element.style.transform = `translate(${x}px, ${y}px) ${ANCHOR_TRANSLATE[anchor]}`;\n\n return point;\n};\n\n/** Round pin, its tip at the bottom: the default marker */\nconst pin = (): HTMLElement => {\n const element = document.createElement('div');\n\n element.innerHTML =\n '<svg class=\"isard-marker-pin\" width=\"25\" height=\"34\" viewBox=\"0 0 25 34\" aria-hidden=\"true\">' +\n '<path fill=\"currentColor\" stroke=\"rgb(0 0 0 / 0.25)\" d=\"M12.5 33.5C12.5 33.5 .5 20.6 .5 12.5a12 12 0 0 1 24 0' +\n 'c0 8.1-12 21-12 21z\"/><circle cx=\"12.5\" cy=\"12.5\" r=\"4.5\" fill=\"#fff\"/></svg>';\n\n return element;\n};\n\nexport interface MarkerOptions {\n /** The element to show (default: a round pin) */\n element?: HTMLElement;\n /** Which part of the element sits on the position (default 'center' with an element of your own, 'bottom' for the\n * default pin) */\n anchor?: Anchor;\n /** Shift from the anchor, CSS pixels (default [0, 0]) */\n offset?: Point;\n /** The marker can be dragged over the map, on the relief (default false) */\n draggable?: boolean;\n /** Metres above the ground (default 0): a raised marker has a stem down to its position on the ground */\n height?: number;\n /** Classes added to the element, space separated */\n className?: string;\n}\n\nexport interface MarkerEvent {\n target: Marker;\n lonLat: LonLat;\n}\n\nexport interface MarkerEvents {\n dragstart: MarkerEvent;\n drag: MarkerEvent;\n dragend: MarkerEvent;\n}\n\n/** An element at a position on the map, optionally draggable */\nexport class Marker {\n private readonly element: HTMLElement;\n private readonly anchor: Anchor;\n private readonly events = new Emitter<MarkerEvents>();\n private offset: Point;\n private draggable: boolean;\n private lonLat: LonLat = [0, 0];\n private height: number;\n /** Metres above the ground of what the marker stands on, where its stem ends */\n private base = 0;\n /** The line from a raised marker down to the ground */\n private readonly stem: HTMLElement;\n private map: GeoMap | undefined;\n private popup: Popup | undefined;\n /** While pressed: the press point and the gap between the pointer and the marker's position */\n private grab: { start: Point; gap: Point } | undefined;\n private dragging = false;\n /** The click that ends a drag is not a click on the marker */\n private swallowClick = false;\n\n constructor(options: MarkerOptions = {}) {\n this.element = options.element ?? pin();\n this.anchor = options.anchor ?? (options.element ? 'center' : 'bottom');\n this.offset = options.offset ?? [0, 0];\n this.draggable = options.draggable ?? false;\n this.height = options.height ?? 0;\n this.stem = document.createElement('div');\n this.stem.className = 'isard-marker-stem';\n [this.stem.style.left, this.stem.style.top] = ANCHOR_POINT[this.anchor];\n this.element.append(this.stem);\n this.element.classList.add('isard-marker');\n if (options.className) this.element.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n this.element.classList.toggle('isard-marker-draggable', this.draggable);\n this.element.addEventListener('pointerdown', (e) => this.down(e));\n this.element.addEventListener('pointermove', (e) => this.move(e));\n this.element.addEventListener('pointerup', (e) => this.up(e));\n this.element.addEventListener('pointercancel', (e) => this.up(e));\n this.element.addEventListener('click', (e) => this.click(e), { capture: true });\n }\n\n getElement(): HTMLElement {\n return this.element;\n }\n\n getLonLat(): LonLat {\n return [...this.lonLat];\n }\n\n setLonLat(lonLat: LonLat): this {\n this.lonLat = [lonLat[0], lonLat[1]];\n this.map?.positionOverlay(this);\n // An open popup of the marker goes with it\n if (this.popup?.isOpen()) this.popup.setLonLat(this.lonLat);\n\n return this;\n }\n\n getHeight(): number {\n return this.height;\n }\n\n /** Metres above the ground: a raised marker has a stem down to `base` metres, what it stands on (a roof, a mesh;\n * the ground by default); its popup is raised too */\n setHeight(height: number, base = 0): this {\n this.height = Number.isFinite(height) ? height : 0;\n this.base = Number.isFinite(base) ? Math.min(base, this.height) : 0;\n this.popup?.setHeight(this.height);\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n setOffset(offset: Point): this {\n this.offset = [offset[0], offset[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n setDraggable(draggable: boolean): this {\n this.draggable = draggable;\n this.element.classList.toggle('isard-marker-draggable', draggable);\n\n return this;\n }\n\n isDraggable(): boolean {\n return this.draggable;\n }\n\n /** A popup that a click on the marker opens and closes, at the marker's position; give it an offset clearing the\n * marker (with the default pin, [0, -34]) */\n setPopup(popup: Popup | undefined): this {\n this.popup?.remove();\n this.popup = popup;\n popup?.setHeight(this.height);\n\n return this;\n }\n\n getPopup(): Popup | undefined {\n return this.popup;\n }\n\n /** Opens the marker's popup, or closes it if open */\n togglePopup(): this {\n if (!this.popup || !this.map) return this;\n if (this.popup.isOpen()) this.popup.remove();\n else this.popup.setLonLat(this.lonLat).addTo(this.map);\n\n return this;\n }\n\n /** Listens to the drag of the marker; returns the function that stops listening */\n on<K extends keyof MarkerEvents>(type: K, listener: (event: MarkerEvents[K]) => void): () => void {\n return this.events.on(type, listener);\n }\n\n addTo(map: GeoMap): this {\n if (this.map === map) return this;\n // From another map: off it first (its popup with it); a popup opened before the marker is added stays open\n if (this.map) this.remove();\n this.map = map;\n map.attachOverlay(this, this.element);\n\n return this;\n }\n\n remove(): this {\n this.popup?.remove();\n this.map?.detachOverlay(this, this.element);\n this.map = undefined;\n this.grab = undefined;\n this.dragging = false;\n this.element.classList.remove('isard-marker-dragging');\n\n return this;\n }\n\n /** @internal */\n position(size: Point): void {\n if (!this.map) return;\n\n const top = place(this.map, this.element, this.lonLat, this.height, this.anchor, this.offset, size);\n const ground = top && this.height !== this.base ? this.map.project(this.lonLat, this.base) : undefined;\n\n if (!top || !ground) {\n this.stem.style.display = 'none';\n\n return;\n }\n\n // From the anchor down to what it stands on, a line turned toward it\n const [dx, dy] = [ground[0] - top[0], ground[1] - top[1]];\n\n this.stem.style.display = '';\n this.stem.style.height = `${Math.hypot(dx, dy)}px`;\n this.stem.style.transform = `rotate(${Math.atan2(dy, dx) - Math.PI / 2}rad)`;\n }\n\n private local(e: PointerEvent): Point | undefined {\n const rect = this.map?.getCanvas().getBoundingClientRect();\n\n return rect && [e.clientX - rect.left, e.clientY - rect.top];\n }\n\n private down(e: PointerEvent): void {\n this.swallowClick = false;\n if (!this.draggable || !this.map || e.button !== 0) return;\n\n // The gap to the position on the ground, below a raised marker\n const point = this.map.project(this.lonLat);\n const at = this.local(e);\n\n if (!point || !at) return;\n // The map must not start panning under the marker\n e.stopPropagation();\n e.preventDefault();\n this.element.setPointerCapture(e.pointerId);\n // The grabbed spot of the marker stays under the pointer, wherever the element was pressed\n this.grab = { start: at, gap: [at[0] - point[0], at[1] - point[1]] };\n this.dragging = false;\n }\n\n private move(e: PointerEvent): void {\n const at = this.local(e);\n\n if (!this.grab || !this.map || !at) return;\n e.stopPropagation();\n\n const { start, gap } = this.grab;\n\n if (!this.dragging && Math.hypot(at[0] - start[0], at[1] - start[1]) < DRAG_TOLERANCE) return;\n\n // On the relief: the ground under the point, read back from the picking pass\n const lonLat = this.map.unproject([at[0] - gap[0], at[1] - gap[1]]);\n\n if (!lonLat) return;\n if (!this.dragging) {\n this.dragging = true;\n this.element.classList.add('isard-marker-dragging');\n this.events.emit('dragstart', { target: this, lonLat: this.getLonLat() });\n }\n this.setLonLat(lonLat);\n this.events.emit('drag', { target: this, lonLat: this.getLonLat() });\n }\n\n private up(e: PointerEvent): void {\n if (!this.grab) return;\n e.stopPropagation();\n this.grab = undefined;\n if (this.element.hasPointerCapture(e.pointerId)) this.element.releasePointerCapture(e.pointerId);\n if (!this.dragging) return;\n this.dragging = false;\n this.swallowClick = true;\n this.element.classList.remove('isard-marker-dragging');\n this.events.emit('dragend', { target: this, lonLat: this.getLonLat() });\n }\n\n private click(e: MouseEvent): void {\n if (this.swallowClick) {\n this.swallowClick = false;\n e.stopImmediatePropagation();\n e.preventDefault();\n\n return;\n }\n if (this.popup) this.togglePopup();\n }\n}\n\nexport interface PopupOptions {\n /** A × button in the corner (default true) */\n closeButton?: boolean;\n /** A click on the map elsewhere closes the popup (default true) */\n closeOnClick?: boolean;\n /** CSS max-width of the popup (default '240px') */\n maxWidth?: string;\n /** Classes added to the popup, space separated */\n className?: string;\n /** Which part of the popup sits on the position, its tip there (default 'bottom': the popup is above the point) */\n anchor?: Anchor;\n /** Shift from the anchor, CSS pixels (default [0, 0]) */\n offset?: Point;\n}\n\nexport interface PopupEvents {\n open: { target: Popup };\n close: { target: Popup };\n}\n\n/** A box of content at a position, its tip pointing at it */\nexport class Popup {\n private readonly container: HTMLElement;\n private readonly content: HTMLElement;\n private readonly closeButton: HTMLButtonElement | undefined;\n private readonly anchor: Anchor;\n private readonly closeOnClick: boolean;\n private readonly events = new Emitter<PopupEvents>();\n private offset: Point;\n private lonLat: LonLat = [0, 0];\n private height = 0;\n private map: GeoMap | undefined;\n private stopListening: (() => void) | undefined;\n\n constructor(options: PopupOptions = {}) {\n this.anchor = options.anchor ?? 'bottom';\n this.offset = options.offset ?? [0, 0];\n this.closeOnClick = options.closeOnClick ?? true;\n this.container = document.createElement('div');\n this.container.className = `isard-popup isard-popup-anchor-${this.anchor}`;\n if (options.className) this.container.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n this.container.style.maxWidth = options.maxWidth ?? '240px';\n\n const tip = document.createElement('div');\n\n tip.className = 'isard-popup-tip';\n this.content = document.createElement('div');\n this.content.className = 'isard-popup-content';\n if (options.closeButton ?? true) {\n this.container.classList.add('isard-popup-has-close');\n this.closeButton = document.createElement('button');\n this.closeButton.type = 'button';\n this.closeButton.className = 'isard-popup-close';\n this.closeButton.setAttribute('aria-label', 'Close popup');\n this.closeButton.textContent = '×';\n this.closeButton.addEventListener('click', () => this.remove());\n this.content.append(this.closeButton);\n }\n this.container.append(tip, this.content);\n }\n\n getElement(): HTMLElement {\n return this.container;\n }\n\n getLonLat(): LonLat {\n return [...this.lonLat];\n }\n\n setLonLat(lonLat: LonLat): this {\n this.lonLat = [lonLat[0], lonLat[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n setOffset(offset: Point): this {\n this.offset = [offset[0], offset[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n getHeight(): number {\n return this.height;\n }\n\n /** Metres above the ground (default 0); a marker's popup follows the marker's height */\n setHeight(height: number): this {\n this.height = Number.isFinite(height) ? height : 0;\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n /** Content from an HTML string: only for trusted HTML (use `setText` for user or remote data) */\n setHTML(html: string): this {\n const template = document.createElement('template');\n\n template.innerHTML = html;\n\n return this.setDOMContent(template.content);\n }\n\n setText(text: string): this {\n return this.setDOMContent(document.createTextNode(text));\n }\n\n setDOMContent(node: Node): this {\n this.content.replaceChildren(node);\n if (this.closeButton) this.content.append(this.closeButton);\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n isOpen(): boolean {\n return this.map !== undefined;\n }\n\n /** Listens to the popup opening or closing; returns the function that stops listening */\n on<K extends keyof PopupEvents>(type: K, listener: (event: PopupEvents[K]) => void): () => void {\n return this.events.on(type, listener);\n }\n\n addTo(map: GeoMap): this {\n if (this.map === map) return this;\n this.remove();\n this.map = map;\n map.attachOverlay(this, this.container);\n if (this.closeOnClick) {\n // From the next task on: a popup opened by a map click must not be closed by that same click\n queueMicrotask(() => {\n if (this.map === map && !this.stopListening) this.stopListening = map.on('click', () => this.remove());\n });\n }\n this.events.emit('open', { target: this });\n\n return this;\n }\n\n remove(): this {\n if (!this.map) return this;\n this.stopListening?.();\n this.stopListening = undefined;\n this.map.detachOverlay(this, this.container);\n this.map = undefined;\n this.events.emit('close', { target: this });\n\n return this;\n }\n\n /** @internal */\n position(size: Point): void {\n if (this.map) place(this.map, this.container, this.lonLat, this.height, this.anchor, this.offset, size);\n }\n}\n\nexport interface PanelOptions {\n /** The element shown in 3D (a video, an iframe, an image…), laid out at its CSS size */\n element: HTMLElement;\n /** Its width on the ground, metres; its height follows its CSS aspect */\n width: number;\n /** Degrees clockwise from north the side it faces (default 0: it faces north, read from the north) */\n heading?: number;\n /** Degrees it leans back from upright (default 0: standing; 90: lying flat) */\n pitch?: number;\n /** Metres of its bottom edge above the ground (the relief; default 0) */\n height?: number;\n /** Classes added to the element, space separated */\n className?: string;\n}\n\n/** `a × b`, 4 × 4 column-major */\nconst multiply = (a: ArrayLike<number>, b: ArrayLike<number>): number[] =>\n Array.from({ length: 16 }, (_, i) => {\n const [c, r] = [Math.floor(i / 4), i % 4];\n\n return [0, 1, 2, 3].reduce((sum, k) => sum + (a[k * 4 + r] ?? 0) * (b[c * 4 + k] ?? 0), 0);\n });\n\n/**\n * An element standing in 3D at a position: a video, a web page, a sign, `width` metres wide on the ground, facing\n * `heading`. Placed after each frame by a CSS 3D transform (the element is not drawn by WebGL: the scene does not\n * hide it); hidden when its position is behind the camera\n */\nexport class Panel {\n private readonly element: HTMLElement;\n private lonLat: LonLat = [0, 0];\n private width: number;\n private heading: number;\n private pitch: number;\n private height: number;\n private map: GeoMap | undefined;\n /** Its CSS size, read once it is on the page (`resize` reads it again) */\n private size: Point | undefined;\n\n constructor(options: PanelOptions) {\n this.element = options.element;\n this.width = options.width;\n this.heading = options.heading ?? 0;\n this.pitch = options.pitch ?? 0;\n this.height = options.height ?? 0;\n this.element.classList.add('isard-panel');\n if (options.className) this.element.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n }\n\n getElement(): HTMLElement {\n return this.element;\n }\n\n getLonLat(): LonLat {\n return [...this.lonLat];\n }\n\n setLonLat(lonLat: LonLat): this {\n this.lonLat = [lonLat[0], lonLat[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n /** Width (metres), heading and pitch (degrees), height of its bottom edge (metres), as in `PanelOptions` */\n setPlacement(placement: Partial<Pick<PanelOptions, 'width' | 'heading' | 'pitch' | 'height'>>): this {\n this.width = placement.width ?? this.width;\n this.heading = placement.heading ?? this.heading;\n this.pitch = placement.pitch ?? this.pitch;\n this.height = placement.height ?? this.height;\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n /** Reads the element's CSS size again (after it changed) */\n resize(): this {\n this.size = undefined;\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n addTo(map: GeoMap): this {\n if (this.map === map) return this;\n // From another map: off it first (its popup with it); a popup opened before the marker is added stays open\n if (this.map) this.remove();\n this.map = map;\n map.attachOverlay(this, this.element);\n\n return this;\n }\n\n remove(): this {\n this.map?.detachOverlay(this, this.element);\n this.map = undefined;\n this.size = undefined;\n\n return this;\n }\n\n /** @internal */\n position(viewport: Point): void {\n const map = this.map;\n\n if (!map) return;\n this.size ??= [this.element.offsetWidth || 300, this.element.offsetHeight || 150];\n\n const [w, h] = this.size;\n const ground = map.elevationAt(this.lonLat) ?? 0;\n const local = map.engine.localMatrix(this.lonLat[0], this.lonLat[1], ground);\n // The element's pixels to the local frame (metres, x east, y north, z up): its bottom edge centered on the\n // position, `height` up, facing `heading`, leant back by `pitch`\n const rad = Math.PI / 180;\n const [hd, pt] = [this.heading * rad, this.pitch * rad];\n const s = this.width / w;\n // Across it (left to right as read from the side it faces), and up it\n const [ax, ay] = [-Math.cos(hd), Math.sin(hd)];\n const [ux, uy, uz] = [-Math.sin(hd) * Math.sin(pt), -Math.cos(hd) * Math.sin(pt), Math.cos(pt)];\n const top = h * s;\n const origin = [-ax * (this.width / 2) + ux * top, -ay * (this.width / 2) + uy * top, this.height + uz * top];\n const toLocal = [ax * s, ay * s, 0, 0, -ux * s, -uy * s, -uz * s, 0, 0, 0, 0, 0, ...origin, 1];\n // Clip space to the map's CSS pixels; the depth flattened\n const [vw, vh] = viewport;\n const toScreen = [vw / 2, 0, 0, 0, 0, -vh / 2, 0, 0, 0, 0, 0, 0, vw / 2, vh / 2, 0, 1];\n const clip = multiply(local, toLocal);\n // Behind the camera (its center): hidden\n const centerW = (clip[3] ?? 0) * (w / 2) + (clip[7] ?? 0) * (h / 2) + (clip[15] ?? 0);\n\n // Hidden without touching its display (the page's layout of its content)\n if (!(centerW > 0)) {\n this.element.style.visibility = 'hidden';\n\n return;\n }\n this.element.style.visibility = '';\n\n // Its depth axis the identity, out of the rest: its points have no depth, and a transform that cannot be\n // inverted is not drawn\n const m = multiply(toScreen, clip);\n\n m.splice(8, 4, 0, 0, 1, 0);\n [2, 6, 14].forEach((k) => {\n m[k] = 0;\n });\n this.element.style.transform = `matrix3d(${m.join(',')})`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"overlay.js","sourceRoot":"","sources":["../../src/ui/overlay.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DOM overlays tied to a position: markers and popups. The map places them all in one pass after each frame it draws\n * (camera moves, finer relief arriving), with a CSS transform from `map.project`: the browser only composites them,\n * nothing is laid out again.\n */\nimport type { GeoMap } from '../map.ts';\nimport type { LonLat, Point } from '../types.ts';\nimport { RAD } from '../util/geo.ts';\n\n/** Which part of the element sits on the position */\nexport type Anchor =\n | 'center'\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-left'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-right';\n\nconst ANCHOR_TRANSLATE: Record<Anchor, string> = {\n center: 'translate(-50%, -50%)',\n top: 'translate(-50%, 0)',\n bottom: 'translate(-50%, -100%)',\n left: 'translate(0, -50%)',\n right: 'translate(-100%, -50%)',\n 'top-left': 'translate(0, 0)',\n 'top-right': 'translate(-100%, 0)',\n 'bottom-left': 'translate(0, -100%)',\n 'bottom-right': 'translate(-100%, -100%)',\n};\n\n/** Where the anchor lies within the element, CSS percentages: the stem of a raised marker starts there */\nconst ANCHOR_POINT: Record<Anchor, [string, string]> = {\n center: ['50%', '50%'],\n top: ['50%', '0'],\n bottom: ['50%', '100%'],\n left: ['0', '50%'],\n right: ['100%', '50%'],\n 'top-left': ['0', '0'],\n 'top-right': ['100%', '0'],\n 'bottom-left': ['0', '100%'],\n 'bottom-right': ['100%', '100%'],\n};\n\n/** Overlays further than this out of the canvas (CSS pixels) are hidden: no part of them can show, and huge\n * transforms near the horizon would only cost the compositor */\nconst MARGIN = 500;\n/** A press on a draggable marker that moves less than this (CSS pixels) is a click */\nconst DRAG_TOLERANCE = 3;\n\n/** @internal What the map places after each frame */\nexport interface Positioned {\n /** Places the overlay for the current camera; `size` is the canvas size in CSS pixels */\n position(size: Point): void;\n}\n\n/** Typed listeners of an overlay */\nclass Emitter<E> {\n private readonly listeners: { [K in keyof E]?: Set<(event: E[K]) => void> } = {};\n\n on<K extends keyof E>(type: K, listener: (event: E[K]) => void): () => void {\n const set = this.listeners[type] ?? new Set();\n\n this.listeners[type] = set;\n set.add(listener);\n\n return () => set.delete(listener);\n }\n\n emit<K extends keyof E>(type: K, event: E[K]): void {\n this.listeners[type]?.forEach((listener) => {\n listener(event);\n });\n }\n}\n\n/** Moves `element` so that its anchor sits on `lonLat`, `height` metres above the ground, or hides it when the\n * position is out of sight; returns the screen point */\nconst place = (\n map: GeoMap,\n element: HTMLElement,\n lonLat: LonLat,\n height: number,\n anchor: Anchor,\n offset: Point,\n size: Point,\n): Point | undefined => {\n const point = map.project(lonLat, height);\n const visible =\n point !== undefined &&\n point[0] > -MARGIN &&\n point[0] < size[0] + MARGIN &&\n point[1] > -MARGIN &&\n point[1] < size[1] + MARGIN;\n\n if (!visible) {\n element.style.display = 'none';\n\n return undefined;\n }\n element.style.display = '';\n\n // Whole pixels: a fractional translation blurs text and icons\n const x = Math.round(point[0] + offset[0]);\n const y = Math.round(point[1] + offset[1]);\n\n element.style.transform = `translate(${x}px, ${y}px) ${ANCHOR_TRANSLATE[anchor]}`;\n\n return point;\n};\n\n/** Round pin, its tip at the bottom: the default marker */\nconst pin = (): HTMLElement => {\n const element = document.createElement('div');\n\n element.innerHTML =\n '<svg class=\"isard-marker-pin\" width=\"25\" height=\"34\" viewBox=\"0 0 25 34\" aria-hidden=\"true\">' +\n '<path fill=\"currentColor\" stroke=\"rgb(0 0 0 / 0.25)\" d=\"M12.5 33.5C12.5 33.5 .5 20.6 .5 12.5a12 12 0 0 1 24 0' +\n 'c0 8.1-12 21-12 21z\"/><circle cx=\"12.5\" cy=\"12.5\" r=\"4.5\" fill=\"#fff\"/></svg>';\n\n return element;\n};\n\nexport interface MarkerOptions {\n /** The element to show (default: a round pin) */\n element?: HTMLElement;\n /** Which part of the element sits on the position (default 'center' with an element of your own, 'bottom' for the\n * default pin) */\n anchor?: Anchor;\n /** Shift from the anchor, CSS pixels (default [0, 0]) */\n offset?: Point;\n /** The marker can be dragged over the map, on the relief (default false) */\n draggable?: boolean;\n /** Metres above the ground (default 0): a raised marker has a stem down to its position on the ground */\n height?: number;\n /** Classes added to the element, space separated */\n className?: string;\n}\n\nexport interface MarkerEvent {\n target: Marker;\n lonLat: LonLat;\n}\n\nexport interface MarkerEvents {\n dragstart: MarkerEvent;\n drag: MarkerEvent;\n dragend: MarkerEvent;\n}\n\n/** An element at a position on the map, optionally draggable */\nexport class Marker {\n private readonly element: HTMLElement;\n private readonly anchor: Anchor;\n private readonly events = new Emitter<MarkerEvents>();\n private offset: Point;\n private draggable: boolean;\n private lonLat: LonLat = [0, 0];\n private height: number;\n /** Metres above the ground of what the marker stands on, where its stem ends */\n private base = 0;\n /** The line from a raised marker down to the ground */\n private readonly stem: HTMLElement;\n private map: GeoMap | undefined;\n private popup: Popup | undefined;\n /** While pressed: the press point and the gap between the pointer and the marker's position */\n private grab: { start: Point; gap: Point } | undefined;\n private dragging = false;\n /** The click that ends a drag is not a click on the marker */\n private swallowClick = false;\n\n constructor(options: MarkerOptions = {}) {\n this.element = options.element ?? pin();\n this.anchor = options.anchor ?? (options.element ? 'center' : 'bottom');\n this.offset = options.offset ?? [0, 0];\n this.draggable = options.draggable ?? false;\n this.height = options.height ?? 0;\n this.stem = document.createElement('div');\n this.stem.className = 'isard-marker-stem';\n [this.stem.style.left, this.stem.style.top] = ANCHOR_POINT[this.anchor];\n this.element.append(this.stem);\n this.element.classList.add('isard-marker');\n if (options.className) this.element.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n this.element.classList.toggle('isard-marker-draggable', this.draggable);\n this.element.addEventListener('pointerdown', (e) => this.down(e));\n this.element.addEventListener('pointermove', (e) => this.move(e));\n this.element.addEventListener('pointerup', (e) => this.up(e));\n this.element.addEventListener('pointercancel', (e) => this.up(e));\n this.element.addEventListener('click', (e) => this.click(e), { capture: true });\n }\n\n getElement(): HTMLElement {\n return this.element;\n }\n\n getLonLat(): LonLat {\n return [...this.lonLat];\n }\n\n setLonLat(lonLat: LonLat): this {\n this.lonLat = [lonLat[0], lonLat[1]];\n this.map?.positionOverlay(this);\n // An open popup of the marker goes with it\n if (this.popup?.isOpen()) this.popup.setLonLat(this.lonLat);\n\n return this;\n }\n\n getHeight(): number {\n return this.height;\n }\n\n /** Metres above the ground: a raised marker has a stem down to `base` metres, what it stands on (a roof, a mesh;\n * the ground by default); its popup is raised too */\n setHeight(height: number, base = 0): this {\n this.height = Number.isFinite(height) ? height : 0;\n this.base = Number.isFinite(base) ? Math.min(base, this.height) : 0;\n this.popup?.setHeight(this.height);\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n setOffset(offset: Point): this {\n this.offset = [offset[0], offset[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n setDraggable(draggable: boolean): this {\n this.draggable = draggable;\n this.element.classList.toggle('isard-marker-draggable', draggable);\n\n return this;\n }\n\n isDraggable(): boolean {\n return this.draggable;\n }\n\n /** A popup that a click on the marker opens and closes, at the marker's position; give it an offset clearing the\n * marker (with the default pin, [0, -34]) */\n setPopup(popup: Popup | undefined): this {\n this.popup?.remove();\n this.popup = popup;\n popup?.setHeight(this.height);\n\n return this;\n }\n\n getPopup(): Popup | undefined {\n return this.popup;\n }\n\n /** Opens the marker's popup, or closes it if open */\n togglePopup(): this {\n if (!this.popup || !this.map) return this;\n if (this.popup.isOpen()) this.popup.remove();\n else this.popup.setLonLat(this.lonLat).addTo(this.map);\n\n return this;\n }\n\n /** Listens to the drag of the marker; returns the function that stops listening */\n on<K extends keyof MarkerEvents>(type: K, listener: (event: MarkerEvents[K]) => void): () => void {\n return this.events.on(type, listener);\n }\n\n addTo(map: GeoMap): this {\n if (this.map === map) return this;\n // From another map: off it first (its popup with it); a popup opened before the marker is added stays open\n if (this.map) this.remove();\n this.map = map;\n map.attachOverlay(this, this.element);\n\n return this;\n }\n\n remove(): this {\n this.popup?.remove();\n this.map?.detachOverlay(this, this.element);\n this.map = undefined;\n this.grab = undefined;\n this.dragging = false;\n this.element.classList.remove('isard-marker-dragging');\n\n return this;\n }\n\n /** @internal */\n position(size: Point): void {\n if (!this.map) return;\n\n const top = place(this.map, this.element, this.lonLat, this.height, this.anchor, this.offset, size);\n const ground = top && this.height !== this.base ? this.map.project(this.lonLat, this.base) : undefined;\n\n if (!top || !ground) {\n this.stem.style.display = 'none';\n\n return;\n }\n\n // From the anchor down to what it stands on, a line turned toward it\n const [dx, dy] = [ground[0] - top[0], ground[1] - top[1]];\n\n this.stem.style.display = '';\n this.stem.style.height = `${Math.hypot(dx, dy)}px`;\n this.stem.style.transform = `rotate(${Math.atan2(dy, dx) - Math.PI / 2}RAD)`;\n }\n\n private local(e: PointerEvent): Point | undefined {\n const rect = this.map?.getCanvas().getBoundingClientRect();\n\n return rect && [e.clientX - rect.left, e.clientY - rect.top];\n }\n\n private down(e: PointerEvent): void {\n this.swallowClick = false;\n if (!this.draggable || !this.map || e.button !== 0) return;\n\n // The gap to the position on the ground, below a raised marker\n const point = this.map.project(this.lonLat);\n const at = this.local(e);\n\n if (!point || !at) return;\n // The map must not start panning under the marker\n e.stopPropagation();\n e.preventDefault();\n this.element.setPointerCapture(e.pointerId);\n // The grabbed spot of the marker stays under the pointer, wherever the element was pressed\n this.grab = { start: at, gap: [at[0] - point[0], at[1] - point[1]] };\n this.dragging = false;\n }\n\n private move(e: PointerEvent): void {\n const at = this.local(e);\n\n if (!this.grab || !this.map || !at) return;\n e.stopPropagation();\n\n const { start, gap } = this.grab;\n\n if (!this.dragging && Math.hypot(at[0] - start[0], at[1] - start[1]) < DRAG_TOLERANCE) return;\n\n // On the relief: the ground under the point, read back from the picking pass\n const lonLat = this.map.unproject([at[0] - gap[0], at[1] - gap[1]]);\n\n if (!lonLat) return;\n if (!this.dragging) {\n this.dragging = true;\n this.element.classList.add('isard-marker-dragging');\n this.events.emit('dragstart', { target: this, lonLat: this.getLonLat() });\n }\n this.setLonLat(lonLat);\n this.events.emit('drag', { target: this, lonLat: this.getLonLat() });\n }\n\n private up(e: PointerEvent): void {\n if (!this.grab) return;\n e.stopPropagation();\n this.grab = undefined;\n if (this.element.hasPointerCapture(e.pointerId)) this.element.releasePointerCapture(e.pointerId);\n if (!this.dragging) return;\n this.dragging = false;\n this.swallowClick = true;\n this.element.classList.remove('isard-marker-dragging');\n this.events.emit('dragend', { target: this, lonLat: this.getLonLat() });\n }\n\n private click(e: MouseEvent): void {\n if (this.swallowClick) {\n this.swallowClick = false;\n e.stopImmediatePropagation();\n e.preventDefault();\n\n return;\n }\n if (this.popup) this.togglePopup();\n }\n}\n\nexport interface PopupOptions {\n /** A × button in the corner (default true) */\n closeButton?: boolean;\n /** A click on the map elsewhere closes the popup (default true) */\n closeOnClick?: boolean;\n /** CSS max-width of the popup (default '240px') */\n maxWidth?: string;\n /** Classes added to the popup, space separated */\n className?: string;\n /** Which part of the popup sits on the position, its tip there (default 'bottom': the popup is above the point) */\n anchor?: Anchor;\n /** Shift from the anchor, CSS pixels (default [0, 0]) */\n offset?: Point;\n}\n\nexport interface PopupEvents {\n open: { target: Popup };\n close: { target: Popup };\n}\n\n/** A box of content at a position, its tip pointing at it */\nexport class Popup {\n private readonly container: HTMLElement;\n private readonly content: HTMLElement;\n private readonly closeButton: HTMLButtonElement | undefined;\n private readonly anchor: Anchor;\n private readonly closeOnClick: boolean;\n private readonly events = new Emitter<PopupEvents>();\n private offset: Point;\n private lonLat: LonLat = [0, 0];\n private height = 0;\n private map: GeoMap | undefined;\n private stopListening: (() => void) | undefined;\n\n constructor(options: PopupOptions = {}) {\n this.anchor = options.anchor ?? 'bottom';\n this.offset = options.offset ?? [0, 0];\n this.closeOnClick = options.closeOnClick ?? true;\n this.container = document.createElement('div');\n this.container.className = `isard-popup isard-popup-anchor-${this.anchor}`;\n if (options.className) this.container.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n this.container.style.maxWidth = options.maxWidth ?? '240px';\n\n const tip = document.createElement('div');\n\n tip.className = 'isard-popup-tip';\n this.content = document.createElement('div');\n this.content.className = 'isard-popup-content';\n if (options.closeButton ?? true) {\n this.container.classList.add('isard-popup-has-close');\n this.closeButton = document.createElement('button');\n this.closeButton.type = 'button';\n this.closeButton.className = 'isard-popup-close';\n this.closeButton.setAttribute('aria-label', 'Close popup');\n this.closeButton.textContent = '×';\n this.closeButton.addEventListener('click', () => this.remove());\n this.content.append(this.closeButton);\n }\n this.container.append(tip, this.content);\n }\n\n getElement(): HTMLElement {\n return this.container;\n }\n\n getLonLat(): LonLat {\n return [...this.lonLat];\n }\n\n setLonLat(lonLat: LonLat): this {\n this.lonLat = [lonLat[0], lonLat[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n setOffset(offset: Point): this {\n this.offset = [offset[0], offset[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n getHeight(): number {\n return this.height;\n }\n\n /** Metres above the ground (default 0); a marker's popup follows the marker's height */\n setHeight(height: number): this {\n this.height = Number.isFinite(height) ? height : 0;\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n /** Content from an HTML string: only for trusted HTML (use `setText` for user or remote data) */\n setHTML(html: string): this {\n const template = document.createElement('template');\n\n template.innerHTML = html;\n\n return this.setDOMContent(template.content);\n }\n\n setText(text: string): this {\n return this.setDOMContent(document.createTextNode(text));\n }\n\n setDOMContent(node: Node): this {\n this.content.replaceChildren(node);\n if (this.closeButton) this.content.append(this.closeButton);\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n isOpen(): boolean {\n return this.map !== undefined;\n }\n\n /** Listens to the popup opening or closing; returns the function that stops listening */\n on<K extends keyof PopupEvents>(type: K, listener: (event: PopupEvents[K]) => void): () => void {\n return this.events.on(type, listener);\n }\n\n addTo(map: GeoMap): this {\n if (this.map === map) return this;\n this.remove();\n this.map = map;\n map.attachOverlay(this, this.container);\n if (this.closeOnClick) {\n // From the next task on: a popup opened by a map click must not be closed by that same click\n queueMicrotask(() => {\n if (this.map === map && !this.stopListening) this.stopListening = map.on('click', () => this.remove());\n });\n }\n this.events.emit('open', { target: this });\n\n return this;\n }\n\n remove(): this {\n if (!this.map) return this;\n this.stopListening?.();\n this.stopListening = undefined;\n this.map.detachOverlay(this, this.container);\n this.map = undefined;\n this.events.emit('close', { target: this });\n\n return this;\n }\n\n /** @internal */\n position(size: Point): void {\n if (this.map) place(this.map, this.container, this.lonLat, this.height, this.anchor, this.offset, size);\n }\n}\n\nexport interface PanelOptions {\n /** The element shown in 3D (a video, an iframe, an image…), laid out at its CSS size */\n element: HTMLElement;\n /** Its width on the ground, metres; its height follows its CSS aspect */\n width: number;\n /** Degrees clockwise from north the side it faces (default 0: it faces north, read from the north) */\n heading?: number;\n /** Degrees it leans back from upright (default 0: standing; 90: lying flat) */\n pitch?: number;\n /** Metres of its bottom edge above the ground (the relief; default 0) */\n height?: number;\n /** Classes added to the element, space separated */\n className?: string;\n}\n\n/** `a × b`, 4 × 4 column-major */\nconst multiply = (a: ArrayLike<number>, b: ArrayLike<number>): number[] =>\n Array.from({ length: 16 }, (_, i) => {\n const [c, r] = [Math.floor(i / 4), i % 4];\n\n return [0, 1, 2, 3].reduce((sum, k) => sum + (a[k * 4 + r] ?? 0) * (b[c * 4 + k] ?? 0), 0);\n });\n\n/**\n * An element standing in 3D at a position: a video, a web page, a sign, `width` metres wide on the ground, facing\n * `heading`. Placed after each frame by a CSS 3D transform (the element is not drawn by WebGL: the scene does not\n * hide it); hidden when its position is behind the camera\n */\nexport class Panel {\n private readonly element: HTMLElement;\n private lonLat: LonLat = [0, 0];\n private width: number;\n private heading: number;\n private pitch: number;\n private height: number;\n private map: GeoMap | undefined;\n /** Its CSS size, read once it is on the page (`resize` reads it again) */\n private size: Point | undefined;\n\n constructor(options: PanelOptions) {\n this.element = options.element;\n this.width = options.width;\n this.heading = options.heading ?? 0;\n this.pitch = options.pitch ?? 0;\n this.height = options.height ?? 0;\n this.element.classList.add('isard-panel');\n if (options.className) this.element.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n }\n\n getElement(): HTMLElement {\n return this.element;\n }\n\n getLonLat(): LonLat {\n return [...this.lonLat];\n }\n\n setLonLat(lonLat: LonLat): this {\n this.lonLat = [lonLat[0], lonLat[1]];\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n /** Width (metres), heading and pitch (degrees), height of its bottom edge (metres), as in `PanelOptions` */\n setPlacement(placement: Partial<Pick<PanelOptions, 'width' | 'heading' | 'pitch' | 'height'>>): this {\n this.width = placement.width ?? this.width;\n this.heading = placement.heading ?? this.heading;\n this.pitch = placement.pitch ?? this.pitch;\n this.height = placement.height ?? this.height;\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n /** Reads the element's CSS size again (after it changed) */\n resize(): this {\n this.size = undefined;\n this.map?.positionOverlay(this);\n\n return this;\n }\n\n addTo(map: GeoMap): this {\n if (this.map === map) return this;\n // From another map: off it first (its popup with it); a popup opened before the marker is added stays open\n if (this.map) this.remove();\n this.map = map;\n map.attachOverlay(this, this.element);\n\n return this;\n }\n\n remove(): this {\n this.map?.detachOverlay(this, this.element);\n this.map = undefined;\n this.size = undefined;\n\n return this;\n }\n\n /** @internal */\n position(viewport: Point): void {\n const map = this.map;\n\n if (!map) return;\n this.size ??= [this.element.offsetWidth || 300, this.element.offsetHeight || 150];\n\n const [w, h] = this.size;\n const ground = map.elevationAt(this.lonLat) ?? 0;\n const local = map.engine.localMatrix(this.lonLat[0], this.lonLat[1], ground);\n // The element's pixels to the local frame (metres, x east, y north, z up): its bottom edge centered on the\n // position, `height` up, facing `heading`, leant back by `pitch`\n const [hd, pt] = [this.heading * RAD, this.pitch * RAD];\n const s = this.width / w;\n // Across it (left to right as read from the side it faces), and up it\n const [ax, ay] = [-Math.cos(hd), Math.sin(hd)];\n const [ux, uy, uz] = [-Math.sin(hd) * Math.sin(pt), -Math.cos(hd) * Math.sin(pt), Math.cos(pt)];\n const top = h * s;\n const origin = [-ax * (this.width / 2) + ux * top, -ay * (this.width / 2) + uy * top, this.height + uz * top];\n const toLocal = [ax * s, ay * s, 0, 0, -ux * s, -uy * s, -uz * s, 0, 0, 0, 0, 0, ...origin, 1];\n // Clip space to the map's CSS pixels; the depth flattened\n const [vw, vh] = viewport;\n const toScreen = [vw / 2, 0, 0, 0, 0, -vh / 2, 0, 0, 0, 0, 0, 0, vw / 2, vh / 2, 0, 1];\n const clip = multiply(local, toLocal);\n // Behind the camera (its center): hidden\n const centerW = (clip[3] ?? 0) * (w / 2) + (clip[7] ?? 0) * (h / 2) + (clip[15] ?? 0);\n\n // Hidden without touching its display (the page's layout of its content)\n if (!(centerW > 0)) {\n this.element.style.visibility = 'hidden';\n\n return;\n }\n this.element.style.visibility = '';\n\n // Its depth axis the identity, out of the rest: its points have no depth, and a transform that cannot be\n // inverted is not drawn\n const m = multiply(toScreen, clip);\n\n m.splice(8, 4, 0, 0, 1, 0);\n [2, 6, 14].forEach((k) => {\n m[k] = 0;\n });\n this.element.style.transform = `matrix3d(${m.join(',')})`;\n }\n}\n"]}
|
package/dist/ui/search.js
CHANGED
package/dist/ui/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/ui/search.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The search bar: places suggested as the user types (the Géoplateforme's geocoding by default, or yours), the map\n * flying to the one picked. A combobox for screen readers: arrows move in the list, Enter picks, Escape closes.\n */\n\nimport { type GeocodedPlace, geoplateformeGeocode } from '../geoplateforme.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { Control } from './controls.ts';\n\nexport interface SearchOptions {\n /** The places of a text (default: the Géoplateforme's geocoding, France) */\n geocode?: (text: string, signal: AbortSignal) => Promise<GeocodedPlace[]>;\n /** What a pick does (default: a flight there, closer for an address than for a place) */\n onSelect?: (place: GeocodedPlace, map: GeoMap) => void;\n /** Default 'Search a place' */\n placeholder?: string;\n /** Suggestions shown at most (default 8) */\n maxResults?: number;\n}\n\n/** Milliseconds of typing before the text is looked up */\nconst DEBOUNCE_MS = 250;\n\n/** The default pick: a flight to the place, an address seen closer than a town */\nconst flyThere = (place: GeocodedPlace, map: GeoMap) =>\n map.flyTo({ center: place.lonLat, zoom: place.kind === 'address' ? 17 : 14 });\n\n/** A text box and the places it suggests, in a corner of the map */\nexport class SearchControl implements Control {\n private readonly options: SearchOptions;\n private stop: (() => void) | undefined;\n\n constructor(options: SearchOptions = {}) {\n this.options = options;\n }\n\n onAdd(map: GeoMap): HTMLElement {\n const { geocode, onSelect = flyThere, placeholder = 'Search a place', maxResults = 8 } = this.options;\n const lookUp = geocode ?? ((text: string, signal: AbortSignal) => geoplateformeGeocode(text, { signal }));\n const element = document.createElement('div');\n const input = document.createElement('input');\n const list = document.createElement('ul');\n const listId = `isard-search-${Math.random().toString(36).slice(2)}`;\n const state: {\n places: GeocodedPlace[];\n active: number;\n timer?: ReturnType<typeof setTimeout>;\n query?: AbortController;\n } = { places: [], active: -1 };\n\n element.className = 'isard-ctrl-search';\n input.type = 'search';\n input.placeholder = placeholder;\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-label', placeholder);\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-controls', listId);\n input.setAttribute('aria-expanded', 'false');\n list.id = listId;\n list.setAttribute('role', 'listbox');\n list.hidden = true;\n element.append(input, list);\n\n const show = () => {\n list.replaceChildren(\n ...state.places.map((place, i) => {\n const item = document.createElement('li');\n\n item.id = `${listId}-${i}`;\n item.setAttribute('role', 'option');\n item.setAttribute('aria-selected', String(i === state.active));\n item.textContent = place.label;\n // Before the input's blur\n item.addEventListener('pointerdown', (e) => {\n e.preventDefault();\n pick(i);\n });\n\n return item;\n }),\n );\n list.hidden = state.places.length === 0;\n input.setAttribute('aria-expanded', String(!list.hidden));\n if (state.active >= 0) input.setAttribute('aria-activedescendant', `${listId}-${state.active}`);\n else input.removeAttribute('aria-activedescendant');\n };\n const close = () => {\n state.places = [];\n state.active = -1;\n show();\n };\n const pick = (i: number) => {\n const place = state.places[i];\n\n if (!place) return;\n input.value = place.label;\n close();\n onSelect(place, map);\n };\n const search = () => {\n state.query?.abort();\n\n const query = new AbortController();\n\n state.query = query;\n lookUp(input.value, query.signal).then(\n (places) => {\n if (query.signal.aborted) return;\n state.places = places.slice(0, maxResults);\n state.active = -1;\n show();\n },\n (error: unknown) => {\n if (!query.signal.aborted) console.warn(error);\n },\n );\n };\n\n input.addEventListener('input', () => {\n clearTimeout(state.timer);\n state.timer = setTimeout(search, DEBOUNCE_MS);\n });\n input.addEventListener('keydown', (e) => {\n const count = state.places.length;\n\n if (e.key === 'ArrowDown' && count > 0) state.active = (state.active + 1) % count;\n else if (e.key === 'ArrowUp' && count > 0) state.active = (state.active - 1 + count) % count;\n else if (e.key === 'Enter') pick(Math.max(0, state.active));\n else if (e.key === 'Escape') close();\n else return;\n e.preventDefault();\n show();\n });\n input.addEventListener('blur', close);\n // The map's keys (arrows, +, -) are not the input's\n element.addEventListener('keydown', (e) => e.stopPropagation());\n\n this.stop = () => {\n clearTimeout(state.timer);\n state.query?.abort();\n };\n\n return element;\n }\n\n onRemove(): void {\n this.stop?.();\n this.stop = undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/ui/search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAsB,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAe/E,0DAA0D;AAC1D,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,kFAAkF;AAClF,MAAM,QAAQ,GAAG,CAAC,KAAoB,EAAE,GAAW,EAAE,EAAE,CACrD,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAEhF,oEAAoE;AACpE,MAAM,OAAO,aAAa;IACP,OAAO,CAAgB;IAChC,IAAI,CAA2B;IAEvC,YAAY,UAAyB,EAAE;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,GAAW;QACf,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,QAAQ,EAAE,WAAW,GAAG,gBAAgB,EAAE,UAAU,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACtG,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,CAAC,IAAY,EAAE,MAAmB,EAAE,EAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1G,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,gBAAgB,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,KAAK,GAKP,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;QAE/B,OAAO,CAAC,SAAS,GAAG,mBAAmB,CAAC;QACxC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC;QACtB,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;QAChC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACvC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC9C,KAAK,CAAC,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;QAChD,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC5C,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;QACjB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAE5B,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,CAAC,eAAe,CAClB,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAE1C,IAAI,CAAC,EAAE,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACpC,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC;gBAC/B,0BAA0B;gBAC1B,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE;oBACzC,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,IAAI,CAAC,CAAC,CAAC,CAAC;gBACV,CAAC,CAAC,CAAC;gBAEH,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CACH,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;YACxC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAC1D,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;gBAAE,KAAK,CAAC,YAAY,CAAC,uBAAuB,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;;gBAC3F,KAAK,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;QACtD,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;YAClB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAClB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,KAAK,EAAE,CAAC;YACR,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;YAErB,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;YAEpC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CACpC,CAAC,MAAM,EAAE,EAAE;gBACT,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO;gBACjC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;gBAC3C,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAClB,IAAI,EAAE,CAAC;YACT,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;gBACjB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAClE,CAAC,CACF,CAAC;QACJ,CAAC,CAAC;QAEF,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACnC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;YACtC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;YAElC,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,GAAG,CAAC;gBAAE,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;iBAC7E,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC;gBAAE,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;iBACxF,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;iBACvD,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;gBAAE,KAAK,EAAE,CAAC;;gBAChC,OAAO;YACZ,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACtC,oDAAoD;QACpD,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAEhE,IAAI,CAAC,IAAI,GAAG,GAAG,EAAE;YACf,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;QACvB,CAAC,CAAC;QAEF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACxB,CAAC;CACF","sourcesContent":["/**\n * The search bar: places suggested as the user types (the Géoplateforme's geocoding by default, or yours), the map\n * flying to the one picked. A combobox for screen readers: arrows move in the list, Enter picks, Escape closes.\n */\n\nimport { type GeocodedPlace, geoplateformeGeocode } from '../geoplateforme.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { Control } from './controls.ts';\n\nexport interface SearchOptions {\n /** The places of a text (default: the Géoplateforme's geocoding, France) */\n geocode?: (text: string, signal: AbortSignal) => Promise<GeocodedPlace[]>;\n /** What a pick does (default: a flight there, closer for an address than for a place) */\n onSelect?: (place: GeocodedPlace, map: GeoMap) => void;\n /** Default 'Search a place' */\n placeholder?: string;\n /** Suggestions shown at most (default 8) */\n maxResults?: number;\n}\n\n/** Milliseconds of typing before the text is looked up */\nconst DEBOUNCE_MS = 250;\n\n/** The default pick: a flight to the place, an address seen closer than a town */\nconst flyThere = (place: GeocodedPlace, map: GeoMap) =>\n map.flyTo({ center: place.lonLat, zoom: place.kind === 'address' ? 17 : 14 });\n\n/** A text box and the places it suggests, in a corner of the map */\nexport class SearchControl implements Control {\n private readonly options: SearchOptions;\n private stop: (() => void) | undefined;\n\n constructor(options: SearchOptions = {}) {\n this.options = options;\n }\n\n onAdd(map: GeoMap): HTMLElement {\n const { geocode, onSelect = flyThere, placeholder = 'Search a place', maxResults = 8 } = this.options;\n const lookUp = geocode ?? ((text: string, signal: AbortSignal) => geoplateformeGeocode(text, { signal }));\n const element = document.createElement('div');\n const input = document.createElement('input');\n const list = document.createElement('ul');\n const listId = `isard-search-${Math.random().toString(36).slice(2)}`;\n const state: {\n places: GeocodedPlace[];\n active: number;\n timer?: ReturnType<typeof setTimeout>;\n query?: AbortController;\n } = { places: [], active: -1 };\n\n element.className = 'isard-ctrl-search';\n input.type = 'search';\n input.placeholder = placeholder;\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-label', placeholder);\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-controls', listId);\n input.setAttribute('aria-expanded', 'false');\n list.id = listId;\n list.setAttribute('role', 'listbox');\n list.hidden = true;\n element.append(input, list);\n\n const show = () => {\n list.replaceChildren(\n ...state.places.map((place, i) => {\n const item = document.createElement('li');\n\n item.id = `${listId}-${i}`;\n item.setAttribute('role', 'option');\n item.setAttribute('aria-selected', String(i === state.active));\n item.textContent = place.label;\n // Before the input's blur\n item.addEventListener('pointerdown', (e) => {\n e.preventDefault();\n pick(i);\n });\n\n return item;\n }),\n );\n list.hidden = state.places.length === 0;\n input.setAttribute('aria-expanded', String(!list.hidden));\n if (state.active >= 0) input.setAttribute('aria-activedescendant', `${listId}-${state.active}`);\n else input.removeAttribute('aria-activedescendant');\n };\n const close = () => {\n state.places = [];\n state.active = -1;\n show();\n };\n const pick = (i: number) => {\n const place = state.places[i];\n\n if (!place) return;\n input.value = place.label;\n close();\n onSelect(place, map);\n };\n const search = () => {\n state.query?.abort();\n\n const query = new AbortController();\n\n state.query = query;\n lookUp(input.value, query.signal).then(\n (places) => {\n if (query.signal.aborted) return;\n state.places = places.slice(0, maxResults);\n state.active = -1;\n show();\n },\n (error: unknown) => {\n if (!query.signal.aborted) console.warn('isard: search', error);\n },\n );\n };\n\n input.addEventListener('input', () => {\n clearTimeout(state.timer);\n state.timer = setTimeout(search, DEBOUNCE_MS);\n });\n input.addEventListener('keydown', (e) => {\n const count = state.places.length;\n\n if (e.key === 'ArrowDown' && count > 0) state.active = (state.active + 1) % count;\n else if (e.key === 'ArrowUp' && count > 0) state.active = (state.active - 1 + count) % count;\n else if (e.key === 'Enter') pick(Math.max(0, state.active));\n else if (e.key === 'Escape') close();\n else return;\n e.preventDefault();\n show();\n });\n input.addEventListener('blur', close);\n // The map's keys (arrows, +, -) are not the input's\n element.addEventListener('keydown', (e) => e.stopPropagation());\n\n this.stop = () => {\n clearTimeout(state.timer);\n state.query?.abort();\n };\n\n return element;\n }\n\n onRemove(): void {\n this.stop?.();\n this.stop = undefined;\n }\n}\n"]}
|
package/dist/util/animation.js
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
* camera of the engine in use at that frame (it may be replaced during a flight).
|
|
4
4
|
*/
|
|
5
5
|
import { fromMercator, toMercator } from "./geo.js";
|
|
6
|
+
import { clamp } from "./math.js";
|
|
6
7
|
/** MapLibre's default easing: cubic Bézier (0.25, 0.1, 0.25, 1) */
|
|
7
8
|
export const defaultEasing = (t) => {
|
|
8
9
|
if (t <= 0 || t >= 1)
|
|
9
|
-
return
|
|
10
|
+
return clamp(t, 0, 1);
|
|
10
11
|
// Solve x(u) = t for the curve parameter, Newton then bisection
|
|
11
12
|
const [x1, y1, x2, y2] = [0.25, 0.1, 0.25, 1];
|
|
12
13
|
const bezier = (u, a, b) => 3 * a * u * (1 - u) ** 2 + 3 * b * u * u * (1 - u) + u ** 3;
|
|
@@ -16,7 +17,7 @@ export const defaultEasing = (t) => {
|
|
|
16
17
|
const dx = 3 * x1 * (1 - u) ** 2 + 6 * (x2 - x1) * u * (1 - u) + 3 * (1 - x2) * u * u;
|
|
17
18
|
if (Math.abs(x) < 1e-6 || dx === 0)
|
|
18
19
|
break;
|
|
19
|
-
u =
|
|
20
|
+
u = clamp(u - x / dx, 0, 1);
|
|
20
21
|
}
|
|
21
22
|
return bezier(u, y1, y2);
|
|
22
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation.js","sourceRoot":"","sources":["../../src/util/animation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Camera animations: each is a step run every frame by the map (`GeoMap.animate`) until it returns false, setting the\n * camera of the engine in use at that frame (it may be replaced during a flight).\n */\n\nimport type { AnimationOptions, FlyToOptions } from '../types.ts';\nimport type { Camera, Engine } from '../wasm/isard.js';\nimport { fromMercator, toMercator } from './geo.ts';\n\n/** A step of an animation, at `now` (milliseconds, the frame's time): false once done */\nexport type Step = (now: number) => boolean;\n\n/** What a step needs of the engine, read at each frame */\ntype Target = () => Pick<Engine, 'setCamera' | 'clearPreload'>;\n\n/** MapLibre's default easing: cubic Bézier (0.25, 0.1, 0.25, 1) */\nexport const defaultEasing = (t: number): number => {\n if (t <= 0 || t >= 1) return Math.max(0, Math.min(1, t));\n\n // Solve x(u) = t for the curve parameter, Newton then bisection\n const [x1, y1, x2, y2] = [0.25, 0.1, 0.25, 1];\n const bezier = (u: number, a: number, b: number) => 3 * a * u * (1 - u) ** 2 + 3 * b * u * u * (1 - u) + u ** 3;\n let u = t;\n\n for (let i = 0; i < 8; i += 1) {\n const x = bezier(u, x1, x2) - t;\n const dx = 3 * x1 * (1 - u) ** 2 + 6 * (x2 - x1) * u * (1 - u) + 3 * (1 - x2) * u * u;\n\n if (Math.abs(x) < 1e-6 || dx === 0) break;\n u = Math.max(0, Math.min(1, u - x / dx));\n }\n\n return bezier(u, y1, y2);\n};\n\n/** The step of an animated move from `from` to `to`: over `duration` milliseconds (or the options), ease-out by\n * default, the bearing turning the shortest way round */\nexport const easeTo = (engine: Target, from: Camera, to: Camera, options: number | AnimationOptions = 600): Step => {\n const { duration = 600, easing = (t: number) => 1 - (1 - t) ** 3 } =\n typeof options === 'number' ? { duration: options } : options;\n // Shortest way round\n const turn = ((to.bearing - from.bearing + 540) % 360) - 180;\n const start = performance.now();\n\n return (now) => {\n if (now - start >= duration) engine().clearPreload();\n\n const t = duration > 0 ? Math.min(1, (now - start) / duration) : 1;\n const k = easing(t);\n const mix = (a: number, b: number) => a + (b - a) * k;\n\n engine().setCamera(\n mix(from.center[0], to.center[0]),\n mix(from.center[1], to.center[1]),\n mix(from.zoom, to.zoom),\n mix(from.pitch, to.pitch),\n from.bearing + turn * k,\n );\n\n return t < 1;\n };\n};\n\n/**\n * The step of a flight from `from` to `to` that zooms out on its way and back in (van Wijk and Nuij's optimal path, as\n * MapLibre's `flyTo`): long moves stay readable. Pitch and bearing follow the progress. `viewport`: the larger side of\n * the canvas, CSS pixels.\n */\nexport const flyTo = (engine: Target, from: Camera, to: Camera, viewport: number, options: FlyToOptions = {}): Step => {\n const { curve: rho = 1.42, speed = 1.2, easing = defaultEasing } = options;\n const [x0, y0] = toMercator(from.center);\n const [x1, y1] = toMercator(to.center);\n // Across the antimeridian, the short way\n const dx = x1 - x0 - Math.round(x1 - x0);\n const dy = y1 - y0;\n // In pixels at the start zoom (512 px world at zoom 0)\n const world = 512 * 2 ** from.zoom;\n const u1 = Math.hypot(dx, dy) * world;\n const w0 = Math.max(viewport, 1);\n const w1 = w0 / 2 ** (to.zoom - from.zoom);\n const rho2 = rho * rho;\n const r = (i: 0 | 1) => {\n const b = (w1 * w1 - w0 * w0 + (i ? -1 : 1) * rho2 * rho2 * u1 * u1) / (2 * (i ? w1 : w0) * rho2 * u1);\n\n return Math.log(Math.sqrt(b * b + 1) - b);\n };\n // No move on the ground (or nearly): a plain zoom\n const still = u1 < 1e-6 || !Number.isFinite(r(0)) || !Number.isFinite(r(1));\n const r0 = still ? 0 : r(0);\n const length = still ? Math.abs(Math.log(w1 / w0)) / rho : (r(1) - r0) / rho;\n const width = (s: number) =>\n still ? Math.exp((w1 < w0 ? -1 : 1) * rho * s) : Math.cosh(r0) / Math.cosh(r0 + rho * s);\n const along = (s: number) =>\n still ? 0 : (w0 * ((Math.cosh(r0) * Math.tanh(r0 + rho * s) - Math.sinh(r0)) / rho2)) / u1;\n const duration = options.duration ?? (1000 * length) / speed;\n const turn = ((to.bearing - from.bearing + 540) % 360) - 180;\n const start = performance.now();\n\n return (now) => {\n if (now - start >= duration) engine().clearPreload();\n\n const t = duration > 0 ? Math.min(1, (now - start) / duration) : 1;\n const k = easing(t);\n const s = k * length;\n const u = t >= 1 ? 1 : along(s);\n const zoom = t >= 1 ? to.zoom : from.zoom + Math.log2(1 / width(s));\n const [lon, lat] = fromMercator([x0 + dx * u, y0 + dy * u]);\n\n engine().setCamera(lon, lat, zoom, from.pitch + (to.pitch - from.pitch) * k, from.bearing + turn * k);\n\n return t < 1;\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"animation.js","sourceRoot":"","sources":["../../src/util/animation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAQlC,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAU,EAAE;IACjD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5C,gEAAgE;IAChE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChH,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtF,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,KAAK,CAAC;YAAE,MAAM;QAC1C,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF;yDACyD;AACzD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,EAAU,EAAE,UAAqC,GAAG,EAAQ,EAAE;IACjH,MAAM,EAAE,QAAQ,GAAG,GAAG,EAAE,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAChE,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,qBAAqB;IACrB,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC7D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,OAAO,CAAC,GAAG,EAAE,EAAE;QACb,IAAI,GAAG,GAAG,KAAK,IAAI,QAAQ;YAAE,MAAM,EAAE,CAAC,YAAY,EAAE,CAAC;QAErD,MAAM,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAEtD,MAAM,EAAE,CAAC,SAAS,CAChB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EACjC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EACjC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EACvB,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EACzB,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,CACxB,CAAC;QAEF,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,EAAU,EAAE,QAAgB,EAAE,UAAwB,EAAE,EAAQ,EAAE;IACpH,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IAC3E,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACvC,yCAAyC;IACzC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACnB,uDAAuD;IACvD,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;IACvB,MAAM,CAAC,GAAG,CAAC,CAAQ,EAAE,EAAE;QACrB,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;QAEvG,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC;IACF,kDAAkD;IAClD,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;IAC7E,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAC1B,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;IAC3F,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAC1B,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC;IAC7D,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC7D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,OAAO,CAAC,GAAG,EAAE,EAAE;QACb,IAAI,GAAG,GAAG,KAAK,IAAI,QAAQ;YAAE,MAAM,EAAE,CAAC,YAAY,EAAE,CAAC;QAErD,MAAM,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAE5D,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;QAEtG,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * Camera animations: each is a step run every frame by the map (`GeoMap.animate`) until it returns false, setting the\n * camera of the engine in use at that frame (it may be replaced during a flight).\n */\n\nimport type { AnimationOptions, FlyToOptions } from '../types.ts';\nimport type { Camera, Engine } from '../wasm/isard.js';\nimport { fromMercator, toMercator } from './geo.ts';\nimport { clamp } from './math.ts';\n\n/** A step of an animation, at `now` (milliseconds, the frame's time): false once done */\nexport type Step = (now: number) => boolean;\n\n/** What a step needs of the engine, read at each frame */\ntype Target = () => Pick<Engine, 'setCamera' | 'clearPreload'>;\n\n/** MapLibre's default easing: cubic Bézier (0.25, 0.1, 0.25, 1) */\nexport const defaultEasing = (t: number): number => {\n if (t <= 0 || t >= 1) return clamp(t, 0, 1);\n\n // Solve x(u) = t for the curve parameter, Newton then bisection\n const [x1, y1, x2, y2] = [0.25, 0.1, 0.25, 1];\n const bezier = (u: number, a: number, b: number) => 3 * a * u * (1 - u) ** 2 + 3 * b * u * u * (1 - u) + u ** 3;\n let u = t;\n\n for (let i = 0; i < 8; i += 1) {\n const x = bezier(u, x1, x2) - t;\n const dx = 3 * x1 * (1 - u) ** 2 + 6 * (x2 - x1) * u * (1 - u) + 3 * (1 - x2) * u * u;\n\n if (Math.abs(x) < 1e-6 || dx === 0) break;\n u = clamp(u - x / dx, 0, 1);\n }\n\n return bezier(u, y1, y2);\n};\n\n/** The step of an animated move from `from` to `to`: over `duration` milliseconds (or the options), ease-out by\n * default, the bearing turning the shortest way round */\nexport const easeTo = (engine: Target, from: Camera, to: Camera, options: number | AnimationOptions = 600): Step => {\n const { duration = 600, easing = (t: number) => 1 - (1 - t) ** 3 } =\n typeof options === 'number' ? { duration: options } : options;\n // Shortest way round\n const turn = ((to.bearing - from.bearing + 540) % 360) - 180;\n const start = performance.now();\n\n return (now) => {\n if (now - start >= duration) engine().clearPreload();\n\n const t = duration > 0 ? Math.min(1, (now - start) / duration) : 1;\n const k = easing(t);\n const mix = (a: number, b: number) => a + (b - a) * k;\n\n engine().setCamera(\n mix(from.center[0], to.center[0]),\n mix(from.center[1], to.center[1]),\n mix(from.zoom, to.zoom),\n mix(from.pitch, to.pitch),\n from.bearing + turn * k,\n );\n\n return t < 1;\n };\n};\n\n/**\n * The step of a flight from `from` to `to` that zooms out on its way and back in (van Wijk and Nuij's optimal path, as\n * MapLibre's `flyTo`): long moves stay readable. Pitch and bearing follow the progress. `viewport`: the larger side of\n * the canvas, CSS pixels.\n */\nexport const flyTo = (engine: Target, from: Camera, to: Camera, viewport: number, options: FlyToOptions = {}): Step => {\n const { curve: rho = 1.42, speed = 1.2, easing = defaultEasing } = options;\n const [x0, y0] = toMercator(from.center);\n const [x1, y1] = toMercator(to.center);\n // Across the antimeridian, the short way\n const dx = x1 - x0 - Math.round(x1 - x0);\n const dy = y1 - y0;\n // In pixels at the start zoom (512 px world at zoom 0)\n const world = 512 * 2 ** from.zoom;\n const u1 = Math.hypot(dx, dy) * world;\n const w0 = Math.max(viewport, 1);\n const w1 = w0 / 2 ** (to.zoom - from.zoom);\n const rho2 = rho * rho;\n const r = (i: 0 | 1) => {\n const b = (w1 * w1 - w0 * w0 + (i ? -1 : 1) * rho2 * rho2 * u1 * u1) / (2 * (i ? w1 : w0) * rho2 * u1);\n\n return Math.log(Math.sqrt(b * b + 1) - b);\n };\n // No move on the ground (or nearly): a plain zoom\n const still = u1 < 1e-6 || !Number.isFinite(r(0)) || !Number.isFinite(r(1));\n const r0 = still ? 0 : r(0);\n const length = still ? Math.abs(Math.log(w1 / w0)) / rho : (r(1) - r0) / rho;\n const width = (s: number) =>\n still ? Math.exp((w1 < w0 ? -1 : 1) * rho * s) : Math.cosh(r0) / Math.cosh(r0 + rho * s);\n const along = (s: number) =>\n still ? 0 : (w0 * ((Math.cosh(r0) * Math.tanh(r0 + rho * s) - Math.sinh(r0)) / rho2)) / u1;\n const duration = options.duration ?? (1000 * length) / speed;\n const turn = ((to.bearing - from.bearing + 540) % 360) - 180;\n const start = performance.now();\n\n return (now) => {\n if (now - start >= duration) engine().clearPreload();\n\n const t = duration > 0 ? Math.min(1, (now - start) / duration) : 1;\n const k = easing(t);\n const s = k * length;\n const u = t >= 1 ? 1 : along(s);\n const zoom = t >= 1 ? to.zoom : from.zoom + Math.log2(1 / width(s));\n const [lon, lat] = fromMercator([x0 + dx * u, y0 + dy * u]);\n\n engine().setCamera(lon, lat, zoom, from.pitch + (to.pitch - from.pitch) * k, from.bearing + turn * k);\n\n return t < 1;\n };\n};\n"]}
|
package/dist/util/color.d.ts
CHANGED
|
@@ -6,3 +6,13 @@
|
|
|
6
6
|
export type Rgba = [r: number, g: number, b: number, a: number];
|
|
7
7
|
/** A CSS color to RGBA 0-1; undefined if it is not one */
|
|
8
8
|
export declare const parseCssColor: (value: unknown) => Rgba | undefined;
|
|
9
|
+
/** Colors of values: `[[value, color], …]` in increasing values, linear in between */
|
|
10
|
+
export type Ramp = [value: number, color: string][];
|
|
11
|
+
/** A CSS color to RGBA 0-1 (see `parseCssColor`); black if unknown or missing */
|
|
12
|
+
export declare const parseColor: (color: string) => [r: number, g: number, b: number, a: number];
|
|
13
|
+
/** 256 RGBA texels of a ramp over its value range, and that range */
|
|
14
|
+
export declare const rampTexels: (ramp: Ramp) => {
|
|
15
|
+
rgba: Uint8Array;
|
|
16
|
+
min: number;
|
|
17
|
+
max: number;
|
|
18
|
+
};
|
package/dist/util/color.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* CSS colors to RGBA 0-1: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, `rgb()` and `rgba()`, `hsl()` and `hsla()` (comma
|
|
3
|
-
* or space syntax, `/` before the alpha, percentages), the CSS named colors and `transparent`. No DOM: the workers use
|
|
4
|
-
* it too.
|
|
5
|
-
*/
|
|
1
|
+
import { clamp } from "./math.js";
|
|
6
2
|
/** The CSS named colors, as name and `rrggbb` pairs */
|
|
7
3
|
const NAMES = 'aliceblue f0f8ff antiquewhite faebd7 aqua 00ffff aquamarine 7fffd4 azure f0ffff beige f5f5dc bisque ffe4c4 ' +
|
|
8
4
|
'black 000000 blanchedalmond ffebcd blue 0000ff blueviolet 8a2be2 brown a52a2a burlywood deb887 cadetblue 5f9ea0 ' +
|
|
@@ -37,7 +33,8 @@ const namedHex = (name) => {
|
|
|
37
33
|
}
|
|
38
34
|
return named.get(name);
|
|
39
35
|
};
|
|
40
|
-
|
|
36
|
+
/** A channel in [0, 1], 0 if not a number */
|
|
37
|
+
const unit = (v) => (Number.isFinite(v) ? clamp(v, 0, 1) : 0);
|
|
41
38
|
const hex = (digits) => {
|
|
42
39
|
if (!/^[0-9a-f]+$/.test(digits) || ![3, 4, 6, 8].includes(digits.length))
|
|
43
40
|
return undefined;
|
|
@@ -49,7 +46,7 @@ const hex = (digits) => {
|
|
|
49
46
|
const alpha = (p) => {
|
|
50
47
|
if (p === undefined)
|
|
51
48
|
return 1;
|
|
52
|
-
return
|
|
49
|
+
return unit(p.endsWith('%') ? Number.parseFloat(p) / 100 : Number.parseFloat(p));
|
|
53
50
|
};
|
|
54
51
|
const hsl = (h, s, l) => {
|
|
55
52
|
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
@@ -86,11 +83,34 @@ export const parseCssColor = (value) => {
|
|
|
86
83
|
return undefined;
|
|
87
84
|
const a = alpha(parts[3]);
|
|
88
85
|
if (match[1].startsWith('rgb')) {
|
|
89
|
-
const channel = (p) =>
|
|
86
|
+
const channel = (p) => unit(p.endsWith('%') ? Number.parseFloat(p) / 100 : Number.parseFloat(p) / 255);
|
|
90
87
|
return [channel(parts[0] ?? ''), channel(parts[1] ?? ''), channel(parts[2] ?? ''), a];
|
|
91
88
|
}
|
|
92
89
|
const h = Number.parseFloat(parts[0] ?? '') / 360;
|
|
93
|
-
const [r, g, b] = hsl(h,
|
|
90
|
+
const [r, g, b] = hsl(h, unit(Number.parseFloat(parts[1] ?? '') / 100), unit(Number.parseFloat(parts[2] ?? '') / 100));
|
|
94
91
|
return [r, g, b, a];
|
|
95
92
|
};
|
|
93
|
+
/** A CSS color to RGBA 0-1 (see `parseCssColor`); black if unknown or missing */
|
|
94
|
+
export const parseColor = (color) => {
|
|
95
|
+
return parseCssColor(color) ?? [0, 0, 0, 1];
|
|
96
|
+
};
|
|
97
|
+
/** 256 RGBA texels of a ramp over its value range, and that range */
|
|
98
|
+
export const rampTexels = (ramp) => {
|
|
99
|
+
const stops = ramp.map(([v, c]) => [v, parseColor(c)]).sort((a, b) => a[0] - b[0]);
|
|
100
|
+
const min = stops[0]?.[0] ?? 0;
|
|
101
|
+
const max = stops.at(-1)?.[0] ?? 1;
|
|
102
|
+
const rgba = new Uint8Array(256 * 4);
|
|
103
|
+
for (let i = 0; i < 256; i += 1) {
|
|
104
|
+
const v = min + ((max - min) * i) / 255;
|
|
105
|
+
let k = 0;
|
|
106
|
+
while (k + 1 < stops.length && (stops[k + 1]?.[0] ?? 0) < v)
|
|
107
|
+
k += 1;
|
|
108
|
+
const [v0, c0] = stops[k] ?? [min, [0, 0, 0, 1]];
|
|
109
|
+
const [v1, c1] = stops[k + 1] ?? [v0, c0];
|
|
110
|
+
const t = v1 > v0 ? clamp((v - v0) / (v1 - v0), 0, 1) : 0;
|
|
111
|
+
for (let j = 0; j < 4; j += 1)
|
|
112
|
+
rgba[i * 4 + j] = Math.round(((c0[j] ?? 0) + ((c1[j] ?? 0) - (c0[j] ?? 0)) * t) * 255);
|
|
113
|
+
}
|
|
114
|
+
return { rgba, min, max };
|
|
115
|
+
};
|
|
96
116
|
//# sourceMappingURL=color.js.map
|
package/dist/util/color.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/util/color.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CSS colors to RGBA 0-1: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, `rgb()` and `rgba()`, `hsl()` and `hsla()` (comma\n * or space syntax, `/` before the alpha, percentages), the CSS named colors and `transparent`. No DOM: the workers use\n * it too.\n */\n\nexport type Rgba = [r: number, g: number, b: number, a: number];\n\n/** The CSS named colors, as name and `rrggbb` pairs */\nconst NAMES =\n 'aliceblue f0f8ff antiquewhite faebd7 aqua 00ffff aquamarine 7fffd4 azure f0ffff beige f5f5dc bisque ffe4c4 ' +\n 'black 000000 blanchedalmond ffebcd blue 0000ff blueviolet 8a2be2 brown a52a2a burlywood deb887 cadetblue 5f9ea0 ' +\n 'chartreuse 7fff00 chocolate d2691e coral ff7f50 cornflowerblue 6495ed cornsilk fff8dc crimson dc143c ' +\n 'cyan 00ffff darkblue 00008b darkcyan 008b8b darkgoldenrod b8860b darkgray a9a9a9 darkgreen 006400 ' +\n 'darkgrey a9a9a9 darkkhaki bdb76b darkmagenta 8b008b darkolivegreen 556b2f darkorange ff8c00 darkorchid 9932cc ' +\n 'darkred 8b0000 darksalmon e9967a darkseagreen 8fbc8f darkslateblue 483d8b darkslategray 2f4f4f ' +\n 'darkslategrey 2f4f4f darkturquoise 00ced1 darkviolet 9400d3 deeppink ff1493 deepskyblue 00bfff dimgray 696969 ' +\n 'dimgrey 696969 dodgerblue 1e90ff firebrick b22222 floralwhite fffaf0 forestgreen 228b22 fuchsia ff00ff ' +\n 'gainsboro dcdcdc ghostwhite f8f8ff gold ffd700 goldenrod daa520 gray 808080 green 008000 greenyellow adff2f ' +\n 'grey 808080 honeydew f0fff0 hotpink ff69b4 indianred cd5c5c indigo 4b0082 ivory fffff0 khaki f0e68c ' +\n 'lavender e6e6fa lavenderblush fff0f5 lawngreen 7cfc00 lemonchiffon fffacd lightblue add8e6 lightcoral f08080 ' +\n 'lightcyan e0ffff lightgoldenrodyellow fafad2 lightgray d3d3d3 lightgreen 90ee90 lightgrey d3d3d3 ' +\n 'lightpink ffb6c1 lightsalmon ffa07a lightseagreen 20b2aa lightskyblue 87cefa lightslategray 778899 ' +\n 'lightslategrey 778899 lightsteelblue b0c4de lightyellow ffffe0 lime 00ff00 limegreen 32cd32 linen faf0e6 ' +\n 'magenta ff00ff maroon 800000 mediumaquamarine 66cdaa mediumblue 0000cd mediumorchid ba55d3 ' +\n 'mediumpurple 9370db mediumseagreen 3cb371 mediumslateblue 7b68ee mediumspringgreen 00fa9a ' +\n 'mediumturquoise 48d1cc mediumvioletred c71585 midnightblue 191970 mintcream f5fffa mistyrose ffe4e1 ' +\n 'moccasin ffe4b5 navajowhite ffdead navy 000080 oldlace fdf5e6 olive 808000 olivedrab 6b8e23 orange ffa500 ' +\n 'orangered ff4500 orchid da70d6 palegoldenrod eee8aa palegreen 98fb98 paleturquoise afeeee ' +\n 'palevioletred db7093 papayawhip ffefd5 peachpuff ffdab9 peru cd853f pink ffc0cb plum dda0dd ' +\n 'powderblue b0e0e6 purple 800080 rebeccapurple 663399 red ff0000 rosybrown bc8f8f royalblue 4169e1 ' +\n 'saddlebrown 8b4513 salmon fa8072 sandybrown f4a460 seagreen 2e8b57 seashell fff5ee sienna a0522d ' +\n 'silver c0c0c0 skyblue 87ceeb slateblue 6a5acd slategray 708090 slategrey 708090 snow fffafa ' +\n 'springgreen 00ff7f steelblue 4682b4 tan d2b48c teal 008080 thistle d8bfd8 tomato ff6347 turquoise 40e0d0 ' +\n 'violet ee82ee wheat f5deb3 white ffffff whitesmoke f5f5f5 yellow ffff00 yellowgreen 9acd32';\n\nlet named: Map<string, string> | undefined;\n\nconst namedHex = (name: string): string | undefined => {\n if (!named) {\n const words = NAMES.split(' ');\n\n named = new Map(\n Array.from({ length: Math.floor(words.length / 2) }, (_, i) => [words[2 * i] ?? '', words[2 * i + 1] ?? '']),\n );\n }\n\n return named.get(name);\n};\n\nconst clamp = (v: number) => (Number.isFinite(v) ? Math.max(0, Math.min(1, v)) : 0);\n\nconst hex = (digits: string): Rgba | undefined => {\n if (!/^[0-9a-f]+$/.test(digits) || ![3, 4, 6, 8].includes(digits.length)) return undefined;\n\n const full = digits.length <= 4 ? [...digits].map((h) => h + h).join('') : digits;\n const v = (i: number) => Number.parseInt(full.slice(i, i + 2), 16) / 255;\n\n return [v(0), v(2), v(4), full.length === 8 ? v(6) : 1];\n};\n\n/** An alpha: a number from 0 to 1 or a percentage */\nconst alpha = (p: string | undefined): number => {\n if (p === undefined) return 1;\n\n return clamp(p.endsWith('%') ? Number.parseFloat(p) / 100 : Number.parseFloat(p));\n};\n\nconst hsl = (h: number, s: number, l: number): [number, number, number] => {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const hue = (t: number) => {\n const u = ((t % 1) + 1) % 1;\n\n if (u < 1 / 6) return p + (q - p) * 6 * u;\n if (u < 1 / 2) return q;\n if (u < 2 / 3) return p + (q - p) * (2 / 3 - u) * 6;\n\n return p;\n };\n\n return [hue(h + 1 / 3), hue(h), hue(h - 1 / 3)];\n};\n\n/** A CSS color to RGBA 0-1; undefined if it is not one */\nexport const parseCssColor = (value: unknown): Rgba | undefined => {\n if (typeof value !== 'string') return undefined;\n\n const c = value.trim().toLowerCase();\n\n if (c.startsWith('#')) return hex(c.slice(1));\n if (c === 'transparent') return [0, 0, 0, 0];\n\n const name = namedHex(c);\n\n if (name) return hex(name);\n\n const match = /^(rgba?|hsla?)\\(([^)]*)\\)$/.exec(c);\n\n if (!match?.[1] || match[2] === undefined) return undefined;\n\n const parts = match[2].split(/[\\s,/]+/).filter(Boolean);\n\n if (parts.length < 3 || parts.slice(0, 3).some((p) => Number.isNaN(Number.parseFloat(p)))) return undefined;\n\n const a = alpha(parts[3]);\n\n if (match[1].startsWith('rgb')) {\n const channel = (p: string) => clamp(p.endsWith('%') ? Number.parseFloat(p) / 100 : Number.parseFloat(p) / 255);\n\n return [channel(parts[0] ?? ''), channel(parts[1] ?? ''), channel(parts[2] ?? ''), a];\n }\n\n const h = Number.parseFloat(parts[0] ?? '') / 360;\n const [r, g, b] = hsl(\n h,\n clamp(Number.parseFloat(parts[1] ?? '') / 100),\n clamp(Number.parseFloat(parts[2] ?? '') / 100),\n );\n\n return [r, g, b, a];\n};\n"]}
|
|
1
|
+
{"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/util/color.ts"],"names":[],"mappings":"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","sourcesContent":["import { clamp } from './math.ts';\n/**\n * CSS colors to RGBA 0-1: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, `rgb()` and `rgba()`, `hsl()` and `hsla()` (comma\n * or space syntax, `/` before the alpha, percentages), the CSS named colors and `transparent`. No DOM: the workers use\n * it too.\n */\n\nexport type Rgba = [r: number, g: number, b: number, a: number];\n\n/** The CSS named colors, as name and `rrggbb` pairs */\nconst NAMES =\n 'aliceblue f0f8ff antiquewhite faebd7 aqua 00ffff aquamarine 7fffd4 azure f0ffff beige f5f5dc bisque ffe4c4 ' +\n 'black 000000 blanchedalmond ffebcd blue 0000ff blueviolet 8a2be2 brown a52a2a burlywood deb887 cadetblue 5f9ea0 ' +\n 'chartreuse 7fff00 chocolate d2691e coral ff7f50 cornflowerblue 6495ed cornsilk fff8dc crimson dc143c ' +\n 'cyan 00ffff darkblue 00008b darkcyan 008b8b darkgoldenrod b8860b darkgray a9a9a9 darkgreen 006400 ' +\n 'darkgrey a9a9a9 darkkhaki bdb76b darkmagenta 8b008b darkolivegreen 556b2f darkorange ff8c00 darkorchid 9932cc ' +\n 'darkred 8b0000 darksalmon e9967a darkseagreen 8fbc8f darkslateblue 483d8b darkslategray 2f4f4f ' +\n 'darkslategrey 2f4f4f darkturquoise 00ced1 darkviolet 9400d3 deeppink ff1493 deepskyblue 00bfff dimgray 696969 ' +\n 'dimgrey 696969 dodgerblue 1e90ff firebrick b22222 floralwhite fffaf0 forestgreen 228b22 fuchsia ff00ff ' +\n 'gainsboro dcdcdc ghostwhite f8f8ff gold ffd700 goldenrod daa520 gray 808080 green 008000 greenyellow adff2f ' +\n 'grey 808080 honeydew f0fff0 hotpink ff69b4 indianred cd5c5c indigo 4b0082 ivory fffff0 khaki f0e68c ' +\n 'lavender e6e6fa lavenderblush fff0f5 lawngreen 7cfc00 lemonchiffon fffacd lightblue add8e6 lightcoral f08080 ' +\n 'lightcyan e0ffff lightgoldenrodyellow fafad2 lightgray d3d3d3 lightgreen 90ee90 lightgrey d3d3d3 ' +\n 'lightpink ffb6c1 lightsalmon ffa07a lightseagreen 20b2aa lightskyblue 87cefa lightslategray 778899 ' +\n 'lightslategrey 778899 lightsteelblue b0c4de lightyellow ffffe0 lime 00ff00 limegreen 32cd32 linen faf0e6 ' +\n 'magenta ff00ff maroon 800000 mediumaquamarine 66cdaa mediumblue 0000cd mediumorchid ba55d3 ' +\n 'mediumpurple 9370db mediumseagreen 3cb371 mediumslateblue 7b68ee mediumspringgreen 00fa9a ' +\n 'mediumturquoise 48d1cc mediumvioletred c71585 midnightblue 191970 mintcream f5fffa mistyrose ffe4e1 ' +\n 'moccasin ffe4b5 navajowhite ffdead navy 000080 oldlace fdf5e6 olive 808000 olivedrab 6b8e23 orange ffa500 ' +\n 'orangered ff4500 orchid da70d6 palegoldenrod eee8aa palegreen 98fb98 paleturquoise afeeee ' +\n 'palevioletred db7093 papayawhip ffefd5 peachpuff ffdab9 peru cd853f pink ffc0cb plum dda0dd ' +\n 'powderblue b0e0e6 purple 800080 rebeccapurple 663399 red ff0000 rosybrown bc8f8f royalblue 4169e1 ' +\n 'saddlebrown 8b4513 salmon fa8072 sandybrown f4a460 seagreen 2e8b57 seashell fff5ee sienna a0522d ' +\n 'silver c0c0c0 skyblue 87ceeb slateblue 6a5acd slategray 708090 slategrey 708090 snow fffafa ' +\n 'springgreen 00ff7f steelblue 4682b4 tan d2b48c teal 008080 thistle d8bfd8 tomato ff6347 turquoise 40e0d0 ' +\n 'violet ee82ee wheat f5deb3 white ffffff whitesmoke f5f5f5 yellow ffff00 yellowgreen 9acd32';\n\nlet named: Map<string, string> | undefined;\n\nconst namedHex = (name: string): string | undefined => {\n if (!named) {\n const words = NAMES.split(' ');\n\n named = new Map(\n Array.from({ length: Math.floor(words.length / 2) }, (_, i) => [words[2 * i] ?? '', words[2 * i + 1] ?? '']),\n );\n }\n\n return named.get(name);\n};\n\n/** A channel in [0, 1], 0 if not a number */\nconst unit = (v: number) => (Number.isFinite(v) ? clamp(v, 0, 1) : 0);\n\nconst hex = (digits: string): Rgba | undefined => {\n if (!/^[0-9a-f]+$/.test(digits) || ![3, 4, 6, 8].includes(digits.length)) return undefined;\n\n const full = digits.length <= 4 ? [...digits].map((h) => h + h).join('') : digits;\n const v = (i: number) => Number.parseInt(full.slice(i, i + 2), 16) / 255;\n\n return [v(0), v(2), v(4), full.length === 8 ? v(6) : 1];\n};\n\n/** An alpha: a number from 0 to 1 or a percentage */\nconst alpha = (p: string | undefined): number => {\n if (p === undefined) return 1;\n\n return unit(p.endsWith('%') ? Number.parseFloat(p) / 100 : Number.parseFloat(p));\n};\n\nconst hsl = (h: number, s: number, l: number): [number, number, number] => {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const hue = (t: number) => {\n const u = ((t % 1) + 1) % 1;\n\n if (u < 1 / 6) return p + (q - p) * 6 * u;\n if (u < 1 / 2) return q;\n if (u < 2 / 3) return p + (q - p) * (2 / 3 - u) * 6;\n\n return p;\n };\n\n return [hue(h + 1 / 3), hue(h), hue(h - 1 / 3)];\n};\n\n/** A CSS color to RGBA 0-1; undefined if it is not one */\nexport const parseCssColor = (value: unknown): Rgba | undefined => {\n if (typeof value !== 'string') return undefined;\n\n const c = value.trim().toLowerCase();\n\n if (c.startsWith('#')) return hex(c.slice(1));\n if (c === 'transparent') return [0, 0, 0, 0];\n\n const name = namedHex(c);\n\n if (name) return hex(name);\n\n const match = /^(rgba?|hsla?)\\(([^)]*)\\)$/.exec(c);\n\n if (!match?.[1] || match[2] === undefined) return undefined;\n\n const parts = match[2].split(/[\\s,/]+/).filter(Boolean);\n\n if (parts.length < 3 || parts.slice(0, 3).some((p) => Number.isNaN(Number.parseFloat(p)))) return undefined;\n\n const a = alpha(parts[3]);\n\n if (match[1].startsWith('rgb')) {\n const channel = (p: string) => unit(p.endsWith('%') ? Number.parseFloat(p) / 100 : Number.parseFloat(p) / 255);\n\n return [channel(parts[0] ?? ''), channel(parts[1] ?? ''), channel(parts[2] ?? ''), a];\n }\n\n const h = Number.parseFloat(parts[0] ?? '') / 360;\n const [r, g, b] = hsl(\n h,\n unit(Number.parseFloat(parts[1] ?? '') / 100),\n unit(Number.parseFloat(parts[2] ?? '') / 100),\n );\n\n return [r, g, b, a];\n};\n\n/** Colors of values: `[[value, color], …]` in increasing values, linear in between */\nexport type Ramp = [value: number, color: string][];\n\n/** A CSS color to RGBA 0-1 (see `parseCssColor`); black if unknown or missing */\nexport const parseColor = (color: string): [r: number, g: number, b: number, a: number] => {\n return parseCssColor(color) ?? [0, 0, 0, 1];\n};\n\n/** 256 RGBA texels of a ramp over its value range, and that range */\nexport const rampTexels = (ramp: Ramp): { rgba: Uint8Array; min: number; max: number } => {\n const stops = ramp.map(([v, c]) => [v, parseColor(c)] as const).sort((a, b) => a[0] - b[0]);\n const min = stops[0]?.[0] ?? 0;\n const max = stops.at(-1)?.[0] ?? 1;\n const rgba = new Uint8Array(256 * 4);\n\n for (let i = 0; i < 256; i += 1) {\n const v = min + ((max - min) * i) / 255;\n let k = 0;\n\n while (k + 1 < stops.length && (stops[k + 1]?.[0] ?? 0) < v) k += 1;\n\n const [v0, c0] = stops[k] ?? [min, [0, 0, 0, 1]];\n const [v1, c1] = stops[k + 1] ?? [v0, c0];\n const t = v1 > v0 ? clamp((v - v0) / (v1 - v0), 0, 1) : 0;\n\n for (let j = 0; j < 4; j += 1)\n rgba[i * 4 + j] = Math.round(((c0[j] ?? 0) + ((c1[j] ?? 0) - (c0[j] ?? 0)) * t) * 255);\n }\n\n return { rgba, min, max };\n};\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Requests that fail as one: an error saying which URL answered which status */
|
|
2
|
+
/** A request's failure: `isard: <url>: HTTP <status>` */
|
|
3
|
+
export declare const httpError: (url: string | URL, status: number) => Error;
|
|
4
|
+
/** A response that is ok, else an `httpError` */
|
|
5
|
+
export declare const fetchOk: (url: string | URL, init?: RequestInit) => Promise<Response>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Requests that fail as one: an error saying which URL answered which status */
|
|
2
|
+
/** A request's failure: `isard: <url>: HTTP <status>` */
|
|
3
|
+
export const httpError = (url, status) => new Error(`isard: ${String(url)}: HTTP ${status}`);
|
|
4
|
+
/** A response that is ok, else an `httpError` */
|
|
5
|
+
export const fetchOk = async (url, init) => {
|
|
6
|
+
const response = await fetch(url, init);
|
|
7
|
+
if (!response.ok)
|
|
8
|
+
throw httpError(url, response.status);
|
|
9
|
+
return response;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/util/fetch.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,yDAAyD;AACzD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAiB,EAAE,MAAc,EAAS,EAAE,CACpE,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,GAAG,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;AAErD,iDAAiD;AACjD,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,GAAiB,EAAE,IAAkB,EAAqB,EAAE;IACxF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAExC,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAExD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC","sourcesContent":["/** Requests that fail as one: an error saying which URL answered which status */\n\n/** A request's failure: `isard: <url>: HTTP <status>` */\nexport const httpError = (url: string | URL, status: number): Error =>\n new Error(`isard: ${String(url)}: HTTP ${status}`);\n\n/** A response that is ok, else an `httpError` */\nexport const fetchOk = async (url: string | URL, init?: RequestInit): Promise<Response> => {\n const response = await fetch(url, init);\n\n if (!response.ok) throw httpError(url, response.status);\n\n return response;\n};\n"]}
|
package/dist/util/geo.d.ts
CHANGED
|
@@ -20,5 +20,10 @@ export declare const latitude: (y: number) => number;
|
|
|
20
20
|
export declare const toMercator: ([lon, lat]: readonly [number, number, ...unknown[]]) => [x: number, y: number];
|
|
21
21
|
/** Longitude and latitude of a Mercator x, y */
|
|
22
22
|
export declare const fromMercator: ([x, y]: readonly [number, number]) => [lon: number, lat: number];
|
|
23
|
+
/** Metres per Mercator unit at a Mercator y (towards the south, [0, 1]): the circumference at its latitude (a roof's
|
|
24
|
+
* slopes, a tile's cells run in metres) */
|
|
25
|
+
export declare const metresAt: (y: number) => number;
|
|
23
26
|
/** Metres across a tile of level `z` and row `y` at its middle */
|
|
24
27
|
export declare const tileMetres: (z: number, y: number) => number;
|
|
28
|
+
/** A tile's URL from its source's template: every {z}, {x} and {y} replaced (`z` a level, or a WMTS matrix's id) */
|
|
29
|
+
export declare const tileUrl: (template: string, z: number | string, x: number, y: number) => string;
|
package/dist/util/geo.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { clamp } from "./math.js";
|
|
1
2
|
/**
|
|
2
3
|
* Web Mercator in [0, 1] across the world (y towards the south), for the page and the workers alike: the positions
|
|
3
4
|
* sent to the engine, the tiles of a view, the flights, the label candidates of the vector tiles.
|
|
@@ -16,7 +17,7 @@ export const mercatorX = (lon) => {
|
|
|
16
17
|
};
|
|
17
18
|
/** Mercator y of a latitude (degrees), clamped to the edges of the map */
|
|
18
19
|
export const mercatorY = (lat) => {
|
|
19
|
-
const phi = (
|
|
20
|
+
const phi = clamp(lat, -MAX_LAT, MAX_LAT) * RAD;
|
|
20
21
|
return 0.5 - Math.log(Math.tan(Math.PI / 4 + phi / 2)) / (2 * Math.PI);
|
|
21
22
|
};
|
|
22
23
|
/** Longitude (degrees) of a Mercator x */
|
|
@@ -35,6 +36,11 @@ export const toMercator = ([lon, lat]) => {
|
|
|
35
36
|
export const fromMercator = ([x, y]) => {
|
|
36
37
|
return [longitude(x), latitude(y)];
|
|
37
38
|
};
|
|
39
|
+
/** Metres per Mercator unit at a Mercator y (towards the south, [0, 1]): the circumference at its latitude (a roof's
|
|
40
|
+
* slopes, a tile's cells run in metres) */
|
|
41
|
+
export const metresAt = (y) => EARTH_METRES * Math.cos(Math.atan(Math.sinh(Math.PI * (1 - 2 * y))));
|
|
38
42
|
/** Metres across a tile of level `z` and row `y` at its middle */
|
|
39
|
-
export const tileMetres = (z, y) => (
|
|
43
|
+
export const tileMetres = (z, y) => metresAt((y + 0.5) / 2 ** z) / 2 ** z;
|
|
44
|
+
/** A tile's URL from its source's template: every {z}, {x} and {y} replaced (`z` a level, or a WMTS matrix's id) */
|
|
45
|
+
export const tileUrl = (template, z, x, y) => template.replaceAll('{z}', String(z)).replaceAll('{x}', String(x)).replaceAll('{y}', String(y));
|
|
40
46
|
//# sourceMappingURL=geo.js.map
|
package/dist/util/geo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo.js","sourceRoot":"","sources":["../../src/util/geo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;AAEjC,oGAAoG;AACpG,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,GAAG,GAAG,CAAC;AAEpD,sEAAsE;AACtE,MAAM,OAAO,GAAG,kBAAkB,CAAC;AAEnC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IAC/C,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAC3B,CAAC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IAC/C,MAAM,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"geo.js","sourceRoot":"","sources":["../../src/util/geo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClC;;;GAGG;AAEH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;AAEjC,oGAAoG;AACpG,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,GAAG,GAAG,CAAC;AAEpD,sEAAsE;AACtE,MAAM,OAAO,GAAG,kBAAkB,CAAC;AAEnC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IAC/C,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAC3B,CAAC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE;IAC/C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC;IAEhD,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE;IAC7C,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AACvB,CAAC,CAAC;AAEF,yCAAyC;AACzC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAU,EAAE;IAC5C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AACvE,CAAC,CAAC;AAEF,gDAAgD;AAChD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAA0C,EAA0B,EAAE;IACxG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,gDAAgD;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAA4B,EAA8B,EAAE;IAC5F,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF;2CAC2C;AAC3C,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpH,kEAAkE;AAClE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAElG,oHAAoH;AACpH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,CAAkB,EAAE,CAAS,EAAE,CAAS,EAAU,EAAE,CAC5F,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC","sourcesContent":["import { clamp } from './math.ts';\n/**\n * Web Mercator in [0, 1] across the world (y towards the south), for the page and the workers alike: the positions\n * sent to the engine, the tiles of a view, the flights, the label candidates of the vector tiles.\n */\n\n/** Radians in a degree */\nexport const RAD = Math.PI / 180;\n\n/** The Earth's circumference at the equator, metres (Web Mercator's sphere: WGS 84's major axis) */\nexport const EARTH_METRES = 40_075_016.686;\n\n/** Metres in a degree of latitude (and of longitude at the equator), on that sphere */\nexport const METRES_PER_DEGREE = EARTH_METRES / 360;\n\n/** The latitude where Web Mercator is square: the edges of the map */\nconst MAX_LAT = 85.051128779806589;\n\n/** Mercator x of a longitude (degrees) */\nexport const mercatorX = (lon: number): number => {\n return (lon + 180) / 360;\n};\n\n/** Mercator y of a latitude (degrees), clamped to the edges of the map */\nexport const mercatorY = (lat: number): number => {\n const phi = clamp(lat, -MAX_LAT, MAX_LAT) * RAD;\n\n return 0.5 - Math.log(Math.tan(Math.PI / 4 + phi / 2)) / (2 * Math.PI);\n};\n\n/** Longitude (degrees) of a Mercator x */\nexport const longitude = (x: number): number => {\n return x * 360 - 180;\n};\n\n/** Latitude (degrees) of a Mercator y */\nexport const latitude = (y: number): number => {\n return (Math.atan(Math.sinh(Math.PI * (1 - 2 * y))) * 180) / Math.PI;\n};\n\n/** Mercator x, y of a longitude and latitude */\nexport const toMercator = ([lon, lat]: readonly [number, number, ...unknown[]]): [x: number, y: number] => {\n return [mercatorX(lon), mercatorY(lat)];\n};\n\n/** Longitude and latitude of a Mercator x, y */\nexport const fromMercator = ([x, y]: readonly [number, number]): [lon: number, lat: number] => {\n return [longitude(x), latitude(y)];\n};\n\n/** Metres per Mercator unit at a Mercator y (towards the south, [0, 1]): the circumference at its latitude (a roof's\n * slopes, a tile's cells run in metres) */\nexport const metresAt = (y: number): number => EARTH_METRES * Math.cos(Math.atan(Math.sinh(Math.PI * (1 - 2 * y))));\n\n/** Metres across a tile of level `z` and row `y` at its middle */\nexport const tileMetres = (z: number, y: number): number => metresAt((y + 0.5) / 2 ** z) / 2 ** z;\n\n/** A tile's URL from its source's template: every {z}, {x} and {y} replaced (`z` a level, or a WMTS matrix's id) */\nexport const tileUrl = (template: string, z: number | string, x: number, y: number): string =>\n template.replaceAll('{z}', String(z)).replaceAll('{x}', String(x)).replaceAll('{y}', String(y));\n"]}
|