Bay đến một vị trí dựa trên vị trí cuộn
Sử dụng vị trí cuộn để bay đến một vị trí cụ thể trên bản đồ.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fly to a location based on scroll position</title>
<meta property="og:description" content="Scroll down through the story and the map will fly to the chapter's location." />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/trackasia-gl.css" />
<script src="https://unpkg.com/[email protected]/dist/trackasia-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
#map {
position: fixed;
width: 50%;
}
#features {
width: 50%;
margin-left: 50%;
font-family: sans-serif;
overflow-y: scroll;
background-color: #fafafa;
}
section {
padding: 25px 50px;
line-height: 25px;
border-bottom: 1px solid #ddd;
opacity: 0.25;
font-size: 13px;
}
section.active {
opacity: 1;
}
section:last-child {
border-bottom: none;
margin-bottom: 200px;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="features">
<section id="baker" class="active">
<h3>Heading 1</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="aldgate">
<h3>Heading 2</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="london-bridge">
<h3>Heading 3</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="woolwich">
<h3>Heading 4</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="gloucester">
<h3>Heading 5</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="caulfield-gardens">
<h3>Heading 6</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="telegraph">
<h3>Heading 7</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
<section id="charing-cross">
<h3>Heading 8</h3>
<p>
Demo content: Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed porttitor risus leo, eget sodales felis maximus et. Donec
pulvinar, velit eu ultrices elementum, metus lacus posuere felis, in
elementum augue diam at risus. Phasellus tincidunt felis ut arcu
congue laoreet. Nam non tristique odio. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Maecenas
molestie vitae enim in vehicula. Maecenas placerat nec erat
hendrerit commodo. Aenean gravida, libero et pulvinar euismod,..
</p>
</section>
</div>
<script>
const map = new trackasiagl.Map({
container: 'map',
style: 'https://maps.track-asia.com/styles/v1/streets.json?key=public_key',
center: {"lat":10.762622,"lng":106.660172},
zoom: 15.5,
bearing: 27,
pitch: 45
});
const chapters = {
'baker': {
bearing: 27,
center: [106.660172,10.762622],
zoom: 15.5,
pitch: 20
},
'aldgate': {
duration: 6000,
center: [106.756548,10.681964],
bearing: 150,
zoom: 15,
pitch: 0
},
'london-bridge': {
bearing: 90,
center: [106.74565,10.745506],
zoom: 13,
speed: 0.6,
pitch: 40
},
'woolwich': {
bearing: 90,
center: [106.819906,10.78383],
zoom: 12.3
},
'gloucester': {
bearing: 45,
center: [106.397652,11.386609],
zoom: 15.3,
pitch: 20,
speed: 0.5
},
'caulfield-gardens': {
bearing: 180,
center: [105.583993,10.788252],
zoom: 12.3
},
'telegraph': {
bearing: 90,
center: [106.669818,10.770708],
zoom: 17.3,
pitch: 40
},
'charing-cross': {
bearing: 90,
center: [106.669228,10.771124],
zoom: 14.3,
pitch: 20
}
};
// On every scroll event, check which element is on screen
window.onscroll = function () {
const chapterNames = Object.keys(chapters);
for (let i = 0; i < chapterNames.length; i++) {
const chapterName = chapterNames[i];
if (isElementOnScreen(chapterName)) {
setActiveChapter(chapterName);
break;
}
}
};
let activeChapterName = 'baker';
function setActiveChapter(chapterName) {
if (chapterName === activeChapterName) return;
map.flyTo(chapters[chapterName]);
document.getElementById(chapterName).setAttribute('class', 'active');
document.getElementById(activeChapterName).setAttribute('class', '');
activeChapterName = chapterName;
}
function isElementOnScreen(id) {
const element = document.getElementById(id);
const bounds = element.getBoundingClientRect();
return bounds.top < window.innerHeight && bounds.bottom > 0;
}
</script>
</body>
</html>