Sample application
Last updated
Last updated
This is a sample application showing how to use the Felt SDK to build an app with the following features:
listing the map's layers
toggling layer visibility
moving the viewport to center it on predefined city locations
The commented code in its entirety is shown below.
<!doctype html>
<html lang="en">
<head>
<title>Felt JS SDK</title>
</head>
<body>
<div class="container">
<div id="mapContainer"></div>
<div id="sidebar">
<div id="markers">
<h3>Cities</h3>
</div>
<div id="layers">
<h3>Layers</h3>
</div>
</div>
</div>
<script type="module">
// Load the Felt SDK from the unpkg CDN
import { Felt } from "https://esm.run/@feltmaps/js-sdk";
// Get the map and sidebar elements
const container = document.getElementById("mapContainer");
const markerContainer = document.getElementById("markers");
const layerContainer = document.getElementById("layers");
// Embed the map
const felt = await Felt.embed(container, "u49BWs5EtSI29CpwuwB9CzRiC", {
uiControls: {
showLegend: false,
cooperativeGestures: false,
fullScreenButton: false,
},
});
// Add some cities to the sidebar
const locations = [
{ name: "Oakland", lat: 37.8044, lng: -122.271 },
{ name: "New York", lat: 40.7128, lng: -74.006 },
{ name: "Los Angeles", lat: 34.0522, lng: -118.2437 },
{ name: "Chicago", lat: 41.8781, lng: -87.6298 },
{ name: "Houston", lat: 29.7604, lng: -95.3698 },
{ name: "Phoenix", lat: 33.4484, lng: -112.074 },
];
locations.forEach((location) => {
// create a DOM element with the city name
const marker = document.createElement("div");
marker.classList.add("marker");
marker.innerText = location.name;
// center the viewport on the city when the marker is clicked
marker.addEventListener("click", () => {
felt.setViewport({
center: {
latitude: location.lat,
longitude: location.lng,
},
zoom: 10,
});
});
// add the marker to the sidebar
markerContainer.appendChild(marker);
});
// a helper function to toggle the visibility of a layer
async function setLayerVisibility(previousVisibility, layer) {
if (previousVisibility) {
felt.setLayerVisibility({ hide: [layer.id] });
} else {
felt.setLayerVisibility({ show: [layer.id] });
}
// update the layer's visibility state
layer.visible = !previousVisibility;
}
// get all the layers
felt.getLayers().then((layers) => {
layers.forEach((layer) => {
// create a DOM element to represent the layer
const layerElement = document.createElement("div");
layerElement.classList.add("layer-toggles_toggle");
layerElement.innerHTML = `
<input type="checkbox" id="${layer.id}" ${
layer.visible ? "checked" : ""
}>
<label for="${layer.id}">${layer.name}</label>
`;
// add an event listener to the checkbox to toggle the layer visibility
layerElement
.querySelector("input")
.addEventListener("change", () =>
setLayerVisibility(layer.visible, layer),
);
// add the layer element to the container
layerContainer.appendChild(layerElement);
});
});
</script>
</body>
<style>
body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 13px;
}
.container {
display: grid;
grid-template-columns: 1fr 240px;
height: 100vh;
}
iframe {
display: block;
}
#sidebar {
padding: 1rem;
user-select: none;
}
#markers {
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid #ccc;
}
.marker {
cursor: pointer;
padding: 0.25rem 0;
}
.layer-toggles_toggle {
padding: 0.25rem 0;
margin-left: -4px;
display: flex;
align-items: center;
gap: 0.25rem;
}
h3 {
margin: 0;
margin-bottom: 0.5rem;
}
</style>
</html>