diff --git a/samples/map-external-layer/index.njk b/samples/map-external-layer/index.njk index 1af0e108..6f6577d4 100644 --- a/samples/map-external-layer/index.njk +++ b/samples/map-external-layer/index.njk @@ -3,34 +3,41 @@
-
- Woosmap Style +

Map options

+ +
-
- Third party layer + + +
-
- Opacity - -
+ + +
diff --git a/samples/map-external-layer/index.ts b/samples/map-external-layer/index.ts index ae902fe2..63d387f3 100644 --- a/samples/map-external-layer/index.ts +++ b/samples/map-external-layer/index.ts @@ -2,42 +2,27 @@ const openWeatherMapKey = "723abb7941260adc84c92a1f526bdabb"; // [START woosmap_map_external_layer] let map: woosmap.map.Map; -let styleSelect, layerSelect: HTMLSelectElement; +let styleSelect: HTMLSelectElement; +let layerSelect: HTMLSelectElement; let opacityInput: HTMLInputElement; +let opacityDisplay: HTMLElement; -const centerLatLng: woosmap.map.LatLngLiteral = { - lat: 39.15253, - lng: -97.74332 +const centerLatLng: woosmap.map.LatLngLiteral = { + lat: 45.126643, + lng: 6.073999, }; function initMap() { map = new window.woosmap.map.Map( document.getElementById("map") as HTMLElement, { - zoom: 3, + zoom: 15.64, center: centerLatLng, - styles: [] + mapTypeControl: true, + styles: STYLE_PRESETS.lightgrey, }, ); - const imageMapType = new woosmap.map.ImageMapType({ - url: "https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png", - tileSize: new woosmap.map.Size(256, 256), - maxZoom: 19 - }); - map.overlayMapTypes.insertAt(0, imageMapType); - - const onChangeHandler = () => { - if ( - parseFloat(opacityInput.value) > 1 || - parseFloat(opacityInput.value) < 0 - ) { - alert("Value should be between 0 and 1"); - return; - } - changeStyle(styleSelect.value) - changeLayer(layerSelect.value, parseFloat(opacityInput.value)) - }; styleSelect = document.getElementById( "woosmap-style-select", ) as HTMLSelectElement; @@ -47,63 +32,74 @@ function initMap() { opacityInput = document.getElementById( "opacity-value-input", ) as HTMLInputElement; - styleSelect.addEventListener("change", onChangeHandler); - layerSelect.addEventListener("change", onChangeHandler); - opacityInput.addEventListener("change", onChangeHandler); + opacityDisplay = document.getElementById( + "opacity-value-display", + ) as HTMLElement; + + updateOpacityDisplay(); + applyLayer(layerSelect.value, readOpacity()); + + styleSelect.addEventListener("change", onStyleChange); + layerSelect.addEventListener("change", onLayerChange); + opacityInput.addEventListener("input", updateOpacityDisplay); + opacityInput.addEventListener("change", onOpacityChange); } -function changeStyle(name: String) -{ - let styles; - if(name == "retro") - { - styles = retroStyles - } - else if(name == "lightgrey") - { - styles = lightgreyStyles - } - else if(name=="night") - { - styles = nightStyles - } - else{ - styles = [] - } - map = new window.woosmap.map.Map( - document.getElementById("map") as HTMLElement, - { - zoom: map.getZoom(), - center: map.getCenter(), - styles: styles - }, - ); +function updateOpacityDisplay() { + const opacity = parseFloat(opacityInput.value); + opacityDisplay.textContent = `${Math.round(opacity * 100)}%`; } -function changeLayer(provider: string, opacity: number) -{ - let url - if(provider == "temperature") - { - url = `https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`; - - } - else if(provider == "precipitation") - { - url = `https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`; - } - else +function readOpacity(): number { + const opacity = parseFloat(opacityInput.value); + return isNaN(opacity) ? 1 : opacity; +} + +function onStyleChange() { + applyStyle(styleSelect.value); + // Recreating the map wipes overlays — reapply the current layer. + applyLayer(layerSelect.value, readOpacity()); +} + +function onLayerChange() { + const view = LAYER_VIEWS[layerSelect.value]; + if (view) { + map.flyTo(view); + } + applyLayer(layerSelect.value, readOpacity()); +} + +function onOpacityChange() { + applyLayer(layerSelect.value, readOpacity()); +} + +function applyStyle(name: string) { + const styles = STYLE_PRESETS[name] ?? []; + map = new window.woosmap.map.Map( + document.getElementById("map") as HTMLElement, { - url = `https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png`; - } - const imageMapType = new woosmap.map.ImageMapType({ - url: url, - tileSize: new woosmap.map.Size(256, 256), - maxZoom: 19, - opacity: opacity, - name: "Layer" - }); - map.overlayMapTypes.insertAt(0, imageMapType); + zoom: map.getZoom(), + center: map.getCenter(), + mapTypeControl: true, + styles, + }, + ); +} + +function applyLayer(provider: string, opacity: number) { + map.overlayMapTypes.clear(); + const config = LAYER_CONFIGS[provider]; + if (!config) { + return; + } + map.overlayMapTypes.insertAt( + 0, + new woosmap.map.ImageMapType({ + ...config, + tileSize: new woosmap.map.Size(256, 256), + opacity, + }), + ); } const nightStyles = [ @@ -390,6 +386,41 @@ const lightgreyStyles = [ }, ] +const STYLE_PRESETS: Record = { + retro: retroStyles, + lightgrey: lightgreyStyles, + night: nightStyles, +}; + +const LAYER_CONFIGS: Record = { + pistes: { + url: "https://tiles.opensnowmap.org/pistes/{z}/{x}/{y}.png", + name: "OpenSnowMap", + maxZoom: 19, + }, + temperature: { + url: `https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`, + name: "Temperature", + maxZoom: 19, + }, + precipitation: { + url: `https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`, + name: "Precipitation", + maxZoom: 19, + }, +}; + +const US_VIEW = { + center: { lat: 39.8283, lng: -98.5795 }, + zoom: 4, +}; + +const LAYER_VIEWS: Record = { + pistes: { center: { lat: 45.126643, lng: 6.073999 }, zoom: 15.64 }, + temperature: US_VIEW, + precipitation: US_VIEW, +}; + declare global { interface Window { initMap: () => void; diff --git a/samples/map-external-layer/style.scss b/samples/map-external-layer/style.scss index 2551b021..43f1cfd3 100644 --- a/samples/map-external-layer/style.scss +++ b/samples/map-external-layer/style.scss @@ -7,26 +7,79 @@ #app { height: 100%; } + #selector { - @include map-panel($top: 0px, $left: 0); + @include map-panel($top: 0, $left: 0); + width: 220px; + padding: 12px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } -select{ - width: 100px; -} -input { - width: 92px; +.panel-title { + margin: 0 0 10px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + color: #5f6368; } .select-container { - padding: 2px 0; + display: flex; + flex-direction: column; + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } +} + +.select-container .label { + font-size: 0.8125rem; + font-weight: 500; + color: #202124; + margin-bottom: 4px; +} + +.select-container select { width: 100%; + height: 30px; + box-sizing: border-box; + border: 1px solid #dadce0; + border-radius: 4px; + padding: 0 8px; + font-size: 0.8125rem; + background: #fff; + cursor: pointer; + + &:hover { + border-color: #b8bcc1; + } + + &:focus { + outline: none; + border-color: #1a73e8; + } +} + +.opacity-control { display: flex; - justify-content: space-between; + align-items: center; + gap: 8px; +} + +.opacity-control input[type="range"] { + flex: 1; + accent-color: #1a73e8; + cursor: pointer; } -#selector span { - padding: 0 5px; +#opacity-value-display { + font-variant-numeric: tabular-nums; + font-size: 0.8125rem; + color: #5f6368; + min-width: 36px; + text-align: right; } -/* [END woosmap_map_external_layer] */ \ No newline at end of file +/* [END woosmap_map_external_layer] */