This tutorial will present you the way to construct an animated map utilizing SVG and GSAP.js. The objective is to create an eye catching interplay that’s uncomplicated, light-weight, and doesn’t require using a third-party map API.
The Setup
We’ll use an SVG factor to create our responsive stage. It accommodates:
- a map picture,
- a path,
- circles marking the beginning and finish of the route,
- and two teams for “digital camera” motion
GSAP attracts the trail, strikes our point-of-view, and ties our timeline progress to scroll place. For this, you’ll want to incorporate the next scripts:
- gsap.min.js
- ScrollTrigger.min.js
- DrawSVGPlugin.min.js
- MotionPathPlugin.min.js
Right here’s a minimal demo with all of this working collectively.
Let’s break down the HTML and CSS earlier than strolling via the JS:
<part id="s1"> (scroll down) </part>
<part id="s2">
<svg class="map" viewBox="0 0 1500 1500" preserveAspectRatio="xMidYMid slice">
<g class="pov">
<g fill="#fff" stroke="#223e6b" stroke-width="2" stroke-linejoin="spherical">
<picture href="https://belongings.codepen.io/721952/chs_map.jpg" width="100%" top="100%"/>
<path class="path" fill="none" stroke-width="3.3" d="m742 937 18-52 2-28 2-25-26 4-1-24-41 8-37 4-51 5 10 20 3 26 99-13-3-35"/>
<circle class="dot-start" r="4" cx="742" cy="937"/>
<circle class="dot-end" r="4"/>
</g>
</g>
</svg>
</part>
<part id="s3"> (scroll up) </part>
html, physique {
margin:0;
padding:0;
font-family: "Open Sans", sans-serif;
overscroll-behavior: none;
}
part {
place:relative;
left:0;
prime:0;
width:100%;
top:33vh;
show:flex;
align-items:middle;
justify-content:middle;
}
#s2 {
top:300vh;
}
.map {
place:absolute;
prime:0;
width:100vw;
top:100vh;
}
We’ve acquired sections surrounding the SVG factor simply to provide us some vertical scroll distance. To make the SVG responsive, we use the viewBox and preserveAspectRatio attributes. The previous defines x/y coordinates and width/top facet ratio for drawing the graphics. The latter units the strategy for scaling and cropping. Precise width and top are utilized within the CSS, and our SVG will fill the area accordingly.
To maintain the code concise, a number of styling attributes are utilized on the group-level and overwritten as wanted. The trail knowledge was created by drawing over the map picture in Illustrator, however you should use any SVG editor, and even code it by hand within the browser.
Lastly, we’ve circle components, ‘.dot-start’ and ‘.dot-end’ to brighten the look of our route. The beginning one has fastened cx and cy positioning, which matches the x and y values outlined in the beginning of our path’s d attribute. “.dot-end” can be positioned dynamically in our JS. Talking of…
gsap.timeline({
scrollTrigger:{
set off: '#s2',
begin: '0 0',
finish: '100% 100%',
pin: '.map',
scrub: 1
}
})
.from('.path', { drawSVG: '0 0' }, 0)
.to('.dot-end', { motionPath: '.path', immediateRender: true }, 0)
gsap.set('.pov', { x: 750, y: 750, scale: 2.5 })
gsap.set('.pov g', {
x: -gsap.getProperty('.dot-end', 'x'),
y: -gsap.getProperty('.dot-end', 'y')
})
We’ve created a timeline that scrubs together with the scroll progress of the part wrapping our SVG factor. We’re additionally pinning the SVG factor whereas the timeline progresses. There are two, concurrent tweens in our timeline: one drawing the stroke of our path, and one shifting the top circle alongside that path.
Discover we’re forcing an instantaneous render of the top circle, and never ready for the consumer’s scroll progress to begin the timeline. That is obligatory as a result of that circle’s dynamically decided x/y place will issue into how we middle our point-of-view. First the outer group is pushed to the middle of the stage, the place we are able to additionally set the size to zoom in/out as desired. Then the internal group is shifted left and up utilizing the inverse x/y place of the top circle, successfully shifting every thing to the middle.
Shifting the “Digicam”
Now that we’ve established a stable basis, let’s add some “digital camera” motion. To do that, we’ll create two gsap.quickTo() capabilities. These will tween the x/y place of our internal group primarily based on the situation of the top circle. It’s essential to make use of quickTo() as a substitute of gsap.to() as a result of quickTo() is optimized to run often, and we’re going to name these every time our timeline updates.
Let’s additionally add one other layer of scroll-tethered movement by tweening the size of our map. Relatively than setting it as soon as, including a .fromTo() tween to our timeline permits us to set the outer group’s preliminary values and tween the size over the course of our timeline’s progress.
Right here’s the up to date code:
const xTo = gsap.quickTo('.pov g', 'x', {period:1, ease:'expo'});
const yTo = gsap.quickTo('.pov g', 'y', {period:1, ease:'expo'});
gsap.timeline({
scrollTrigger:{
set off: '#s2',
begin: '0 0',
finish: '100% 100%',
pin: '.map',
scrub: 1
},
onUpdate:()=>{ // Transfer internal group utilizing the inverse place of dot-end
xTo(-gsap.getProperty('.dot-end', 'x'));
yTo(-gsap.getProperty('.dot-end', 'y'));
}
})
.from('.path', { drawSVG: '0 0' }, 0)
.to('.dot-end', { motionPath: '.path', immediateRender: true }, 0)
.fromTo('.pov', { x: 750, y: 750, scale: 2.5 }, { scale: 4, ease:'power1.inOut' }, 0)
gsap.set('.pov g', {
x: -gsap.getProperty('.dot-end', 'x'),
y: -gsap.getProperty('.dot-end', 'y')
})
And right here’s the enhanced demo.
Taking it Additional
At this level, we’ve created a flexible setup that you would be able to simply modify and prolong. To begin exploring your personal customization, attempt altering the map picture and drawn path. As an alternative of a map route, it might present the movement of vitamins in a plant diagram, or draw a squiggly arrow round and thru your journey photographs.
You possibly can additionally add to the scroll-triggered timeline; extra zooming out and in, enjoying with rotation, drawing a number of paths are just some concepts that come to thoughts. The essential factor is to place extra tweens with intention. The above demos have concurrent tweens with matching durations, however in the end you may want some components to start sooner or end later. Planning out and enjoying with the timeline is an iterative course of, however a pleasant aspect impact of our setup is the power to clean ahead and backward as a lot as you want.
Under are a number of extra explorations to encourage you to make your personal scrolling SVG scene:


