mirror of
https://github.com/tabler/tabler.git
synced 2026-10-13 13:47:00 +04:00
Recolor the default map styles with a softer palette
This commit is contained in:
1 parent
9fae876516
commit
993416bfd8
6 files changed
+121
-4
No files matched your search
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/preview": minor
|
||||
"@tabler/docs": patch
|
||||
---
|
||||
|
||||
Updated the map demos with softer map colors: a `tablerMapPalette()` script recolors the `positron` and `dark` styles.
|
||||
@@ -33,10 +33,13 @@ classnames:
|
||||
---
|
||||
import Example from '@components/Example.astro';
|
||||
import Map from '@shared/components/demo/Map.astro';
|
||||
import MapPalette from '@shared/components/demo/MapPalette.astro';
|
||||
import Icon from '@ui/Icon.astro';
|
||||
import { Code } from 'astro:components';
|
||||
import { site } from '@shared/lib/site.ts';
|
||||
|
||||
<MapPalette />
|
||||
|
||||
## Overview
|
||||
|
||||
The map is a small wrapper around [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/), an open-source map library. Tabler gives you the container markup and a short init script. MapLibre draws the tiles, handles zoom, and renders the markers.
|
||||
@@ -107,7 +110,7 @@ Set `style` to the URL of any MapLibre style. OpenFreeMap has five of them:
|
||||
|
||||
| Style | Result |
|
||||
| --- | --- |
|
||||
| `https://tiles.openfreemap.org/styles/positron` | Light gray map, used by the Tabler demos. Markers and data stand out on it. |
|
||||
| `https://tiles.openfreemap.org/styles/positron` | Light gray map, used by the Tabler demos with [softer colors](#map-colors). Markers and data stand out on it. |
|
||||
| `https://tiles.openfreemap.org/styles/dark` | Dark gray map, used by the demos in dark mode. |
|
||||
| `https://tiles.openfreemap.org/styles/liberty` | Street map in color. |
|
||||
| `https://tiles.openfreemap.org/styles/bright` | Street map with stronger colors. |
|
||||
@@ -117,6 +120,20 @@ Set `style` to the URL of any MapLibre style. OpenFreeMap has five of them:
|
||||
<Map mapId="light" />
|
||||
</Example>
|
||||
|
||||
### Map colors
|
||||
|
||||
The Tabler demos make the `positron` and `dark` styles softer: near-white land, pale water and muted labels in light mode, and blue-gray water and roads in dark mode. They do it by changing the paint values of the style layers after the style loads:
|
||||
|
||||
```js
|
||||
map.on('style.load', function () {
|
||||
map.setPaintProperty('background', 'background-color', '#fafaf8')
|
||||
map.setPaintProperty('water', 'fill-color', '#d4dadc')
|
||||
map.setPaintProperty('boundary_2', 'line-color', '#e3cdd0')
|
||||
})
|
||||
```
|
||||
|
||||
The full list of colors for both modes is in the `tablerMapPalette()` function in the source of the [maps preview page](https://preview.tabler.io/maps.html). Copy it to get the same look. The layer names belong to the OpenFreeMap styles, so the function works only with them.
|
||||
|
||||
Styles from other providers work the same way, as long as they follow the MapLibre style format. Check the terms of each provider, as many of them need an API key or a paid plan.
|
||||
|
||||
### Markers
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
---
|
||||
import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
|
||||
import CaptureScript from '@shared/components/CaptureScript.astro'
|
||||
import MapPalette from '@components/demo/MapPalette.astro'
|
||||
---
|
||||
|
||||
<DefaultLayout title="Full Size Map" pageHeader={false} pageMenu="plugins.map-fullsize" pageLibs={['maplibre-gl']} navbarPosition="vertical" wrapperFull>
|
||||
<h1 class="visually-hidden">Full Size Map</h1>
|
||||
<MapPalette />
|
||||
<div class="map flex-fill" id="map-fullsize" role="img" aria-label="Map of Berlin"></div>
|
||||
<CaptureScript>
|
||||
<!-- BEGIN MAP SCRIPT -->
|
||||
@@ -12,7 +14,8 @@ import CaptureScript from '@shared/components/CaptureScript.astro'
|
||||
window.tabler_map ??= {}
|
||||
|
||||
function initMap() {
|
||||
const themeStyle = () => `https://tiles.openfreemap.org/styles/${document.documentElement.getAttribute('data-bs-theme') === 'dark' ? 'dark' : 'positron'}`
|
||||
const theme = () => (document.documentElement.getAttribute('data-bs-theme') === 'dark' ? 'dark' : 'light')
|
||||
const themeStyle = () => `https://tiles.openfreemap.org/styles/${theme() === 'dark' ? 'dark' : 'positron'}`
|
||||
|
||||
const map = new maplibregl.Map({
|
||||
container: 'map-fullsize',
|
||||
@@ -23,6 +26,9 @@ import CaptureScript from '@shared/components/CaptureScript.astro'
|
||||
|
||||
map.addControl(new maplibregl.NavigationControl())
|
||||
|
||||
// Softer map colors, set again each time the style loads
|
||||
map.on('style.load', () => tablerMapPalette(map, theme()))
|
||||
|
||||
// Change the map style when the page theme changes
|
||||
new MutationObserver(() => map.setStyle(themeStyle())).observe(document.documentElement, { attributeFilter: ['data-bs-theme'] })
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
|
||||
import Map from '@components/demo/Map.astro'
|
||||
import MapPalette from '@components/demo/MapPalette.astro'
|
||||
import Card from '@ui/Card.astro'
|
||||
import CardBody from '@ui/CardBody.astro'
|
||||
import maps from '@data/maps.json'
|
||||
@@ -78,6 +79,7 @@ const places = [
|
||||
|
||||
<DefaultLayout title="Maps" pageMenu="plugins.maps" pageLibs={['maplibre-gl']} description="Interactive MapLibre maps — plain, styled, with custom markers and popups.">
|
||||
<DocsLink slot="page-header-actions" path="/ui/components/map" />
|
||||
<MapPalette />
|
||||
<CaptureScript>
|
||||
<script is:inline>
|
||||
// MapLibre draws on a canvas, so a layer needs a plain rgb() color instead of a CSS variable
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
// MapLibre GL map on OpenFreeMap tiles: no account and no access token.
|
||||
// The map follows the page theme: `style` in light mode, `darkStyle` in dark.
|
||||
// With <MapPalette /> on the page, the default styles get softer colors.
|
||||
// Markers written in HTML go in the default slot: each child has `data-lng`
|
||||
// and `data-lat`, holds the marker element, and optionally a `<template>` with
|
||||
// the popup content. Renders nothing unless maps[mapId] exists or `center` is set.
|
||||
@@ -45,6 +46,8 @@ const mapContainerId = `map-${mapId}`;
|
||||
const styleUrl = (name: string) => `https://tiles.openfreemap.org/styles/${name}`;
|
||||
const style = styleUrl(data?.style ?? 'positron');
|
||||
const darkStyle = styleUrl(data?.darkStyle ?? 'dark');
|
||||
// The softer palette (MapPalette.astro) is made for these two styles only
|
||||
const palette = { light: !data?.style || data.style === 'positron', dark: !data?.darkStyle || data.darkStyle === 'dark' };
|
||||
const controls = data?.controls ?? false;
|
||||
const zoom = data?.zoom ?? 13;
|
||||
const center = data?.center ? [data.center[1], data.center[0]] : [13.4049, 52.518827];
|
||||
@@ -74,11 +77,12 @@ const ratioClass = data?.ratio ?? ratio ?? '16x9';
|
||||
data && (
|
||||
<CaptureScript>
|
||||
<!-- BEGIN MAP -->
|
||||
<script is:inline define:vars={{ mapContainerId, style, darkStyle, controls, globe, zoom, center, markers }}>
|
||||
<script is:inline define:vars={{ mapContainerId, style, darkStyle, palette, controls, globe, zoom, center, markers }}>
|
||||
window.tabler_map ??= {};
|
||||
|
||||
function initMap() {
|
||||
const themeStyle = () => (document.documentElement.getAttribute('data-bs-theme') === 'dark' ? darkStyle : style);
|
||||
const theme = () => (document.documentElement.getAttribute('data-bs-theme') === 'dark' ? 'dark' : 'light');
|
||||
const themeStyle = () => (theme() === 'dark' ? darkStyle : style);
|
||||
|
||||
const map = new maplibregl.Map({
|
||||
container: mapContainerId,
|
||||
@@ -87,6 +91,13 @@ const ratioClass = data?.ratio ?? ratio ?? '16x9';
|
||||
center,
|
||||
});
|
||||
|
||||
// Softer map colors, when the page has the palette script
|
||||
map.on('style.load', () => {
|
||||
if (window.tablerMapPalette && palette[theme()]) {
|
||||
window.tablerMapPalette(map, theme());
|
||||
}
|
||||
});
|
||||
|
||||
if (controls) {
|
||||
map.addControl(new maplibregl.NavigationControl());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
// Softer colors for the OpenFreeMap `positron` and `dark` map styles: near-white
|
||||
// land, pale water and muted labels. Defines `window.tablerMapPalette(map, mode)`;
|
||||
// put it on the page once, before the maps. `Map.astro` calls it on each style load.
|
||||
import CaptureScript from '../CaptureScript.astro';
|
||||
---
|
||||
|
||||
<CaptureScript>
|
||||
<!-- BEGIN MAP PALETTE -->
|
||||
<script is:inline>
|
||||
// Paint values by layer id: the first rule that matches a layer is used
|
||||
window.tablerMapPalette = (map, mode) => {
|
||||
const palettes = {
|
||||
light: [
|
||||
[/^background$/, { 'background-color': '#fafaf8' }],
|
||||
[/^(park|landcover_wood)$/, { 'fill-color': 'rgba(234, 241, 233, 0.6)' }],
|
||||
[/^water$/, { 'fill-color': '#d4dadc' }],
|
||||
[/^waterway$/, { 'line-color': '#d1dbdf' }],
|
||||
[/^landcover_(ice_shelf|glacier)$/, { 'fill-color': '#fafaf8' }],
|
||||
[/^landuse_residential$/, { 'fill-color': 'rgba(237, 237, 237, 0.5)' }],
|
||||
[/^building$/, { 'fill-color': '#ededed', 'fill-outline-color': '#dfdfdf' }],
|
||||
[/^road_area_pier$/, { 'fill-color': '#fafaf8' }],
|
||||
[/^road_pier$/, { 'line-color': '#fafaf8' }],
|
||||
[/^highway_path$/, { 'line-color': '#ededed' }],
|
||||
[/^highway_minor$/, { 'line-color': '#e6e6e6' }],
|
||||
[/_casing$/, { 'line-color': '#dddddd' }],
|
||||
[/^tunnel_.*_inner$/, { 'line-color': '#f3f3f3' }],
|
||||
[/^highway_.*_inner$/, { 'line-color': '#ffffff' }],
|
||||
[/_subtle$/, { 'line-color': '#e6e6e6' }],
|
||||
[/^railway.*dashline$/, { 'line-color': '#fafaf8' }],
|
||||
[/^railway/, { 'line-color': '#e3e3e3' }],
|
||||
[/^boundary_/, { 'line-color': '#e3cdd0' }],
|
||||
[/^waterway_line_label$/, { 'text-color': '#7a96a0' }],
|
||||
[/^water_name/, { 'text-color': '#abb6be' }],
|
||||
[/^highway-name/, { 'text-color': '#9aa5ad', 'text-halo-color': 'rgba(255, 255, 255, 0.8)' }],
|
||||
[/^(airport|label_country|label_state)/, { 'text-color': '#8a99a4', 'text-halo-color': 'rgba(255, 255, 255, 0.8)' }],
|
||||
[/^label_/, { 'text-color': '#697b89', 'text-halo-color': 'rgba(255, 255, 255, 0.8)' }],
|
||||
],
|
||||
dark: [
|
||||
[/^background$/, { 'background-color': '#0e0e0e' }],
|
||||
[/^water$/, { 'fill-color': '#2c353c' }],
|
||||
[/^waterway$/, { 'line-color': 'rgb(63, 90, 109)' }],
|
||||
[/^landcover_(ice_shelf|glacier)$/, { 'fill-color': '#0e0e0e' }],
|
||||
[/^landuse_residential$/, { 'fill-color': 'rgba(0, 0, 0, 0.5)' }],
|
||||
[/^(landcover_wood|landuse_park)$/, { 'fill-color': '#121412' }],
|
||||
[/^building$/, { 'fill-color': '#1a1a1a' }],
|
||||
[/^road_area_pier$/, { 'fill-color': '#0e0e0e' }],
|
||||
[/^road_pier$/, { 'line-color': '#0e0e0e' }],
|
||||
[/^highway_path$/, { 'line-color': '#232323' }],
|
||||
[/^highway_minor$/, { 'line-color': 'rgba(65, 71, 88, 0.7)' }],
|
||||
[/_casing$/, { 'line-color': '#232323' }],
|
||||
[/^highway_major_inner$/, { 'line-color': 'rgb(65, 71, 88)' }],
|
||||
[/^highway_motorway_inner$/, { 'line-color': 'rgb(83, 86, 102)' }],
|
||||
[/_subtle$/, { 'line-color': 'rgba(65, 71, 88, 0.6)' }],
|
||||
[/^railway.*dashline$/, { 'line-color': '#0e0e0e' }],
|
||||
[/^railway/, { 'line-color': '#262626' }],
|
||||
[/^boundary_/, { 'line-color': 'rgb(96, 96, 96)' }],
|
||||
[/^water_name$/, { 'text-color': 'rgb(109, 123, 129)', 'text-halo-color': 'rgba(0, 0, 0, 0.7)' }],
|
||||
[/^highway_name/, { 'text-color': 'rgb(120, 126, 137)', 'text-halo-color': 'rgba(0, 0, 0, 0.7)' }],
|
||||
[/^place_(country|state)/, { 'text-color': 'rgb(118, 126, 137)' }],
|
||||
[/^place_/, { 'text-color': 'rgb(204, 208, 228)' }],
|
||||
],
|
||||
};
|
||||
|
||||
map.getStyle().layers.forEach((layer) => {
|
||||
const rule = palettes[mode].find(([pattern]) => pattern.test(layer.id));
|
||||
|
||||
if (rule) {
|
||||
Object.entries(rule[1]).forEach(([property, value]) => map.setPaintProperty(layer.id, property, value));
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<!-- END MAP PALETTE -->
|
||||
</CaptureScript>
|
||||
Reference in new issue
Block a user