Skip to content

Instantly share code, notes, and snippets.

@Hirosaji
Last active July 21, 2021 02:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hirosaji/fc6c210918712e8290677ce7a46bff1d to your computer and use it in GitHub Desktop.
Save Hirosaji/fc6c210918712e8290677ce7a46bff1d to your computer and use it in GitHub Desktop.
Mapbox - ScrollyTelling with FreeCamera API
license: mit
Lat Lng
138.7329828 35.3657013
138.7386975 35.3688119
138.7389558 35.3715163
138.7410046 35.3728774
138.7414248 35.3741608
138.7429713 35.3751555
138.7429616 35.3773758
138.7455283 35.3810341
138.7473013 35.3830195
138.74708 35.3853526
138.7449481 35.386113
138.7424273 35.3890085
138.7421246 35.3900325
138.7388695 35.3908729
138.7345373 35.392543
138.7306413 35.3967174
138.7256413 35.4057174
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.3.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.3.0/mapbox-gl.js"></script>
<script src="https://docs.mapbox.com/mapbox-gl-js/assets/routes.js"></script>
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
<script src="https://d3js.org/d3.v6.min.js"></script>
<style>
body {
margin: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
html,
body {
width: 100%;
height: 300vh;
overflow-x: hidden;
background: #f2efe9;
}
.map-wrapper {
position: fixed;
margin: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100vh;
}
.contents {
position: absolute;
width: 100%;
height: 1000vh;
}
.wrapper {
position: relative;
top: 200px;
}
body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;
}
.title-on-map {
width: 185px;
margin: 40px auto;
padding-left: 15px;
line-height: 1.5em;
overflow:hidden;
z-index: 1;
position: fixed;
}
.title-on-map span {
color: #fff;
background-color: #000;
padding: 0.225rem 0.5rem;
/* Needs prefixing */
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
@supports(mix-blend-mode: lighten) {
.title-on-map::after {
position: absolute;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
background: linear-gradient(60deg, #247847, #42AF6C);
mix-blend-mode: lighten;
}
}
.fixed-top-text {
z-index: 1;
color: #fff;
text-align: center;
top: 80vh;
font-size: 1.6em;
position: relative;
}
.fixed-top-text p {
margin: 5px auto;
}
</style>
</head>
<body>
<h2 class="title-on-map">
<span>ScrollyTelling: <br>Climb Mt. Fuji</span>
</h2>
<div class="map-wrapper">
<div class="map" id="map"></div>
</div>
<div class="contents" id="scrollTarget">
<div class="wrapper"></div>
</div>
<div class="fixed-top-text">
<p>△</p>
<p>Let's scroll</p>
</div>
<script>
const loadFiles = [
d3.csv("yoshida_route.csv"),
d3.csv("camera_route.csv")
];
const scrollArea = document.getElementById('scrollTarget');
const scrollAreaH = scrollArea.offsetHeight;
const supportPageOffset = window.pageXOffset !== undefined;
const isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
Promise.all(loadFiles).then(function (data) {
const yoshida_route = data[0].map(function (d) {
return [d.Lat, d.Lng];
}).reverse();
const camera_route = data[1].map(function (d) {
return [d.Lat, d.Lng];
}).reverse();
mapboxgl.accessToken = 'pk.eyJ1IjoiaGlyb3NhamkiLCJhIjoiY2szOWlqZWNzMDJueTNjcWhyNjhqdXBnOSJ9._6mJT202QqpnMuK-jvMr3g';
// mapboxgl.accessToken = 'pk.eyJ1IjoiaGlyb3NhamkiLCJhIjoiY2tyMnZxMmtlMDB2bjJxbHQ5ZTN4eTd2eCJ9.pQXT1lAyMLVzNur3zOscDg';
const map = new mapboxgl.Map({
container: 'map',
zoom: 12,
center: camera_route[camera_route.length-1],
pitch: 0,
bearing: 0,
style: 'mapbox://styles/mapbox/satellite-v9',
interactive: false
});
// this is the path the camera will look at
const targetRoute = yoshida_route;
// this is the path the camera will move along
const cameraRoute = camera_route;
// this is the path the camera will look at (short)
const shortTargetRoute = camera_route.slice(1);
// add terrain, sky, and line layers once the style has loaded
map.on('load', function () {
map.addSource('mapbox-dem', {
'type': 'raster-dem',
'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
'tileSize': 512,
});
map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 3 });
map.addLayer({
'id': 'sky',
'type': 'sky',
'paint': {
'sky-type': 'atmosphere',
'sky-atmosphere-sun': [0.0, 90.0],
'sky-atmosphere-sun-intensity': 15
}
});
map.addSource('trace', {
type: 'geojson',
data: {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': targetRoute
}
}
});
map.addLayer({
type: 'line',
source: 'trace',
id: 'line',
paint: {
'line-color': '#ffffff',
'line-opacity': 0.5,
'line-width': 5
},
layout: {
'line-cap': 'round',
'line-join': 'round'
}
});
});
// wait for the terrain and sky to load before starting animation
map.on('load', function () {
const cameraAltitude_base = 7800;
// get the overall length of each route so we can interpolate along them
const routeLength = turf.length(turf.lineString(targetRoute));
const cameraRouteLength = turf.length(turf.lineString(targetRoute));
function frame() {
ticking = false;
// rate determines how far through the animation we are
const y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
const rate = (y / scrollAreaH < 0.03) ? 0.03 : y / scrollAreaH;
// find the best value with your eyes
const cameraAltitude = (rate <= 0.03) ?
cameraAltitude_base + ((0.0305 - rate) * 100000) :
cameraAltitude_base + (rate * rate * 10000);
// use the rate to get a point that is the appropriate length along the route
// this approach syncs the camera and route positions ensuring they move
// at roughly equal rates even if they don't contain the same number of points
const alongRoute = turf.along(
turf.lineString(shortTargetRoute),
routeLength * rate
).geometry.coordinates;
const alongCamera = turf.along(
turf.lineString(cameraRoute),
cameraRouteLength * rate
).geometry.coordinates;
const camera = map.getFreeCameraOptions();
// set the position and altitude of the camera
camera.position = mapboxgl.MercatorCoordinate.fromLngLat(
{
lng: alongCamera[0],
lat: alongCamera[1]
},
cameraAltitude
);
// tell the camera to look at a point along the route
camera.lookAtPoint({
lng: alongRoute[0],
lat: alongRoute[1]
});
map.setFreeCameraOptions(camera);
}
let ticking = false;
function scrollEvent() {
if (!ticking) {
requestAnimationFrame(frame);
ticking = true;
}
}
document.addEventListener('scroll', scrollEvent, {passive: true});
});
});
</script>
</body>
Lat Lng
138.7329828 35.3657013
138.7329731 35.3658156
138.7330644 35.3657851
138.7330709 35.3657831
138.7331593 35.3657446
138.733282 35.3656957
138.733396 35.3656168
138.7334598 35.3656124
138.7334492 35.3657698
138.7334636 35.3658678
138.733685 35.3660239
138.733762 35.3660867
138.7338437 35.3661724
138.7339438 35.3663012
138.7340498 35.366304
138.7341556 35.3663875
138.7342929 35.3663018
138.7343726 35.3664573
138.7343914 35.3664898
138.7344221 35.3665366
138.7345415 35.3664727
138.7346797 35.3664302
138.7347462 35.3666493
138.7347628 35.3667165
138.7348835 35.3666268
138.7349106 35.3667412
138.7349404 35.3668668
138.7351085 35.3668216
138.735142 35.3668389
138.7351534 35.3668815
138.7351653 35.3669779
138.7353193 35.3669142
138.735366 35.3671336
138.7355595 35.3670608
138.7355665 35.3672275
138.7357437 35.3671074
138.7358575 35.3673511
138.736002 35.3672266
138.7360785 35.3674994
138.7362755 35.3674685
138.7362795 35.3675984
138.7364713 35.3675336
138.7365753 35.3676916
138.7365866 35.3678873
138.7367454 35.3677562
138.7368217 35.3680103
138.736998 35.367858
138.7370586 35.3680105
138.7370937 35.368057
138.7372393 35.3678227
138.7373488 35.3677894
138.7373912 35.3678633
138.7374396 35.3680001
138.7374661 35.3681399
138.737462 35.3682728
138.7374795 35.3684445
138.7375652 35.3683559
138.737657 35.3682406
138.7377288 35.3685176
138.7378482 35.3683751
138.7379711 35.3682162
138.7381056 35.3684649
138.7381996 35.3685886
138.7382055 35.368732
138.7384128 35.3686722
138.738433 35.3688894
138.7386975 35.3688119
138.7388948 35.3689899
138.7389486 35.3690248
138.7389849 35.3690304
138.7391232 35.3692909
138.739076 35.3693593
138.7388926 35.3694128
138.7387497 35.3694106
138.7386081 35.3695231
138.7386075 35.3696159
138.7385808 35.3696638
138.7387122 35.369712
138.738795 35.3697255
138.7387961 35.369789
138.7386958 35.3699214
138.7387039 35.3699765
138.7388128 35.3700007
138.7390617 35.3700139
138.7391528 35.3700457
138.739178 35.3700615
138.7391823 35.3700957
138.7391473 35.3701885
138.7390914 35.3702657
138.7390132 35.3703472
138.7391478 35.3704473
138.7390132 35.370512
138.738968 35.3705639
138.7390473 35.3706089
138.7393155 35.3706486
138.7393561 35.3706783
138.7393566 35.3707013
138.7392675 35.3708346
138.7392689 35.3708792
138.7393421 35.3709686
138.739268 35.3710275
138.7390911 35.3711038
138.7387801 35.3711569
138.7386581 35.3712765
138.7388774 35.3713203
138.7390941 35.3713596
138.7390028 35.3714561
138.7389558 35.3715163
138.7391566 35.3716166
138.739364 35.3716625
138.7394944 35.3716977
138.739647 35.3716805
138.7398444 35.3716092
138.739946 35.3715725
138.7400208 35.3715749
138.7397383 35.371991
138.7399298 35.3719908
138.7397828 35.3721575
138.7400055 35.372136
138.7399289 35.3723083
138.7400828 35.3723021
138.7399958 35.3724657
138.7403729 35.3724805
138.7404072 35.3725192
138.7402581 35.3726935
138.7401612 35.3728604
138.7405 35.3729299
138.7410046 35.3728774
138.7409646 35.3730296
138.7411032 35.3729932
138.7410118 35.373105
138.7411919 35.3730779
138.7411408 35.3732264
138.7410283 35.373446
138.7410756 35.3736507
138.741248 35.3738081
138.7413802 35.3738029
138.7415224 35.3738255
138.7416237 35.3738655
138.7415886 35.3739809
138.7414248 35.3741608
138.7415122 35.3742495
138.7416708 35.3742426
138.7417914 35.3743221
138.7418832 35.3743008
138.7421246 35.3744755
138.7423079 35.3745012
138.7423935 35.3745883
138.7424526 35.3746824
138.7425132 35.3747649
138.7424103 35.3749304
138.7427021 35.37511
138.7428424 35.3751063
138.7429393 35.3751305
138.7429713 35.3751555
138.7429545 35.3753149
138.7428931 35.3754568
138.7429002 35.3755415
138.7429485 35.3756211
138.7430884 35.3757464
138.7431603 35.3758695
138.7428788 35.3760471
138.7428144 35.3761466
138.7427832 35.3762349
138.7427751 35.3763082
138.7428163 35.3764445
138.7428883 35.3765599
138.7429255 35.3766612
138.7428274 35.3767909
138.7428392 35.3769655
138.7429734 35.3769082
138.743028 35.3769805
138.7430546 35.3770728
138.7429655 35.3771542
138.7429588 35.3772929
138.7429616 35.3773758
138.7431014 35.3774984
138.7432002 35.3774506
138.7433041 35.3773751
138.7434317 35.3773274
138.7434934 35.3773849
138.7434362 35.3775071
138.7434078 35.3776454
138.743455 35.377717
138.7435191 35.3777511
138.7436678 35.3776729
138.7437415 35.377704
138.7437857 35.3778249
138.7437393 35.3779337
138.7436134 35.3780971
138.7435995 35.3782432
138.7437089 35.3783495
138.7437758 35.3783706
138.7438789 35.3784363
138.7439486 35.3783846
138.7440286 35.3784064
138.7439923 35.3784738
138.7440737 35.3785135
138.7440169 35.3785821
138.7439805 35.3786642
138.7440173 35.3787351
138.7440794 35.3787728
138.7441934 35.3787805
138.7442946 35.3786999
138.7444042 35.3786328
138.7445155 35.3786194
138.7446024 35.3786692
138.7446256 35.3787499
138.7446653 35.3788057
138.7446618 35.3789659
138.7444915 35.3790891
138.7443176 35.3792101
138.74434 35.3793471
138.744337 35.3794778
138.7442949 35.379603
138.7443476 35.3796419
138.7444502 35.3796107
138.7445019 35.379552
138.7446688 35.3795586
138.7447144 35.3796841
138.7446667 35.3797708
138.7446791 35.3798478
138.7447947 35.3798207
138.7449393 35.379704
138.7450116 35.3797462
138.7449537 35.3799918
138.7450822 35.379989
138.7451619 35.3799711
138.7452216 35.3799887
138.7451687 35.3800629
138.7450567 35.3801596
138.7450547 35.380219
138.7451299 35.380239
138.7452086 35.3801519
138.745329 35.3801416
138.7453432 35.3801971
138.7452421 35.3803074
138.7452114 35.3805149
138.7452185 35.3806931
138.745298 35.3807484
138.7455487 35.3806597
138.7456924 35.3807124
138.7455829 35.3807522
138.7455283 35.3810341
138.7455546 35.3811097
138.7456606 35.3811183
138.7458388 35.3810168
138.7460186 35.3809676
138.7461143 35.3809997
138.746026 35.3811178
138.745958 35.3812821
138.7459576 35.3814139
138.7460391 35.3814216
138.7463465 35.381354
138.746436 35.3813927
138.7463226 35.3815775
138.7463112 35.3817121
138.7464704 35.3817061
138.7466863 35.3816356
138.7467408 35.3816568
138.7466816 35.3819376
138.7467225 35.3819695
138.746886 35.3819091
138.7468835 35.3821015
138.7468501 35.3822335
138.7467519 35.3823965
138.7465942 35.3825291
138.7464927 35.3826893
138.7464936 35.3827558
138.7467992 35.3827099
138.7469004 35.3827295
138.7468764 35.3829034
138.7468171 35.3831028
138.7468674 35.3831343
138.7472505 35.3829799
138.7473013 35.3830195
138.747242 35.3835379
138.7471948 35.38407
138.7473198 35.3841752
138.7473791 35.3843319
138.747281 35.3844309
138.7471143 35.3844881
138.746994 35.3845181
138.7469059 35.3846052
138.7471357 35.3845918
138.7470495 35.3847081
138.7469873 35.3848195
138.7470464 35.3848767
138.7473499 35.3849928
138.7475261 35.385063
138.7477176 35.385245
138.7474995 35.3852824
138.747302 35.3853137
138.74708 35.3853526
138.7469126 35.3854149
138.7467596 35.3855447
138.7465799 35.3856357
138.7463242 35.3857048
138.7461709 35.3856677
138.7458717 35.3857921
138.7457795 35.3858568
138.7456262 35.3859519
138.7454555 35.38603
138.745276 35.3860785
138.7450973 35.3860451
138.7449481 35.386113
138.7448885 35.3862097
138.7446729 35.3864954
138.7444233 35.3866951
138.7442065 35.3868669
138.7441196 35.3869474
138.7439056 35.3872417
138.7437547 35.3875122
138.7434415 35.3877911
138.743303 35.3879437
138.7431005 35.3882432
138.7427548 35.3885829
138.7426924 35.3886653
138.7424273 35.3890085
138.7422866 35.389362
138.7421442 35.389787
138.7421278 35.3899708
138.7421246 35.3900325
138.7421246 35.3900325
138.7417031 35.3902531
138.7415639 35.3903094
138.7412335 35.3903914
138.7410014 35.390426
138.740814 35.3904225
138.7405022 35.3904289
138.7402012 35.3905102
138.7396633 35.3906504
138.7388695 35.3908729
138.73814 35.391126
138.7375287 35.3913421
138.7370676 35.3915155
138.7368461 35.3915694
138.7365255 35.3916609
138.736163 35.3918137
138.7358214 35.3919657
138.735511 35.39216
138.7351799 35.3923124
138.7347808 35.3924315
138.7345373 35.392543
138.7342864 35.3927447
138.7339099 35.3932125
138.7336808 35.3936565
138.7335761 35.3939094
138.7334275 35.3940063
138.733408 35.3940685
138.7334133 35.3941227
138.7333894 35.3941754
138.7333221 35.3942565
138.7332254 35.3943134
138.7330499 35.3943691
138.7329392 35.3944143
138.7329085 35.3944836
138.7328522 35.3945403
138.732594 35.3946343
138.7326149 35.3946915
138.7326413 35.3947174
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment