Skip to content

Instantly share code, notes, and snippets.

@danielfaust
Created January 12, 2025 12:52
Show Gist options
  • Save danielfaust/12fc45d623a2dd4d334cb0ef4d7854e2 to your computer and use it in GitHub Desktop.
Save danielfaust/12fc45d623a2dd4d334cb0ef4d7854e2 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Map</title>
<link rel='stylesheet' href='../../dist/maplibre-gl.css' />
<script src='../../dist/maplibre-gl-dev.js'></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<style>
.map-overlay {
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
position: absolute;
width: 25%;
top: 0;
left: 0;
padding: 10px;
}
.map-overlay .map-overlay-inner {
background-color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
}
.map-overlay h2 {
line-height: 24px;
display: block;
margin: 0 0 10px;
}
.map-overlay .legend .bar {
height: 10px;
width: 100%;
background: linear-gradient(to right, #fca107, #7f3121);
}
.map-overlay input {
background-color: transparent;
display: inline-block;
width: 100%;
position: relative;
margin: 0;
cursor: ew-resize;
}
</style>
<div id="map"></div>
<div class="map-overlay top">
<div class="map-overlay-inner">
<label>Speed</label>
<input id="slider-speed" type="range" min="0.0" max="0.1" step="0.001" value="0" />
<label>Phase</label>
<input id="slider-phase" type="range" min="0.0" max="6.283" step="0.001" value="0" />
<label>Radius</label>
<input id="slider-radius" type="range" min="0" max="0.1" step="0.001" value="0" />
<label>Size</label>
<input id="slider-scale" type="range" min="0.1" max="4.0" step="0.01" value="0" />
</div>
</div>
<script>
const center = [11.39085, 47.27574];
const map = new maplibregl.Map({
container: 'map',
style: {version: 8, sources: {}, layers:[]},
center: center,
zoom: 11,
hash:true,
optimizeForTerrain: false, // true doesn't fix it
});
map.on('load', () => {
//=====================================================
// Enable display of tile bountaries
//=====================================================
map.showTileBoundaries = true;
//=====================================================
// Add background
//=====================================================
map.addSource("SOURCE-openstreetmap", {
"type": "raster",
"tiles": [ "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" ],
'attribution': '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
"tileSize": 256,
});
map.addLayer({
"id": "LAYER-openstreetmap",
"type": "raster",
"source": "SOURCE-openstreetmap",
}, null);
//=====================================================
// Add image
//=====================================================
var image_offset_1 = 0.04
var la_t_tile_1 = center[1] + 0.025
var lo_l_tile_1 = center[0] - 0.035 + image_offset_1
var la_b_tile_1 = center[1] - 0.025
var lo_r_tile_1 = center[0] + 0.035 + image_offset_1
var url = 'https://i.imgur.com/3IyX7CK.png'
map.addSource('SOURCE-image-1', {
type: 'image',
url: url,
coordinates: [
[lo_l_tile_1, la_t_tile_1],
[lo_r_tile_1, la_t_tile_1],
[lo_r_tile_1, la_b_tile_1],
[lo_l_tile_1, la_b_tile_1]
]
});
map.addLayer({
'id': 'LAYER-image-1',
'type': 'raster',
'source': 'SOURCE-image-1',
});
var i = 0.0;
var speed = 0.02;
var resolution = 1;
var phase = 0.0;
var radius = 0.06;
var scale = 1.0;
var source1 = map.getSource('SOURCE-image-1');
var timer = window.setInterval(function () {
var x = Math.cos(i+phase) * radius * 1.5; // 1.5 because lat-scale != lng-scale, to make it circl-ish
var y = Math.sin(i+phase) * radius;
var la_t_tile_1 = center[1] + 0.025 * scale
var lo_l_tile_1 = center[0] - 0.035 * scale + image_offset_1
var la_b_tile_1 = center[1] - 0.025 * scale
var lo_r_tile_1 = center[0] + 0.035 * scale + image_offset_1
source1.setCoordinates([
[(lo_l_tile_1 + x), (la_t_tile_1 + y)],
[(lo_r_tile_1 + x), (la_t_tile_1 + y)],
[(lo_r_tile_1 + x), (la_b_tile_1 + y)],
[(lo_l_tile_1 + x), (la_b_tile_1 + y)]
])
i += speed*resolution;
}, 25*resolution);
document
.getElementById('slider-speed')
.addEventListener('input', function (e) {
speed = parseFloat(e.target.value);
});
document
.getElementById('slider-phase')
.addEventListener('input', function (e) {
phase = parseFloat(e.target.value);
});
document
.getElementById('slider-radius')
.addEventListener('input', function (e) {
radius = parseFloat(e.target.value);
});
document
.getElementById('slider-scale')
.addEventListener('input', function (e) {
scale = parseFloat(e.target.value);
});
//=====================================================
// Add hillshade
//=====================================================
map.addSource("SOURCE-hillshade", {
"type": "raster-dem",
"url": "https://demotiles.maplibre.org/terrain-tiles/tiles.json",
"tileSize": 256,
});
map.addLayer({
"id": "LAYER-hillshade",
"type": "hillshade",
"source": "SOURCE-hillshade",
"layout": { visibility: 'visible' },
"paint": { 'hillshade-shadow-color': '#473B24' }
}, null);
//=====================================================
// Add terrain
//=====================================================
map.addSource("SOURCE-terrain", {
"type": "raster-dem",
"url": "https://demotiles.maplibre.org/terrain-tiles/tiles.json",
"tileSize": 256,
});
map.setTerrain({
source: "SOURCE-terrain",
exaggeration: 1,
});
map.addControl(
new maplibregl.TerrainControl({
source: 'SOURCE-terrain',
exaggeration: 1
})
);
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment