Есть кривая и на ней расположены точки, и есть один кораблик. Задача состоит в том, чтобы клики по годам должны запоминаться. Т.е. при кликах 2001 -> 2005 -> 2002 кораблик должен «проплыть» от 2001 к 2005 и вернуться к 2002.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<svg width=1000 height=170 id="svg">
<path id="track" d="m20,140c50,0,0,-50,150,-50c50,0,0,-50,150,-50c50,0,0,50,150,50c50,0,0,50,150,50"></path>
<path id="ship" d="m-10,-5l-10,-10l15,3l5,-10l5,10l15,-3l-10,10z"></path>
</svg>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
let count = 8,
len = track.getTotalLength(),
seg = len / (count + 1),
pos = seg,
target = seg;
svg.innerHTML += Array(count).fill(0).map((e, i) => {
let len = seg * (i + 1), p = track.getPointAtLength(len);
return "<g transform=translate("+[p.x, p.y]+") class"+(i?'':'=active')+">" +
" <circle data-len="+len+" r=11></circle>" +
" <rect rx=5 ry=5 x=-20 y=16 width=40 height=19></rect>" +
" <text y=30>"+(2001+i)+"</text>"+
"</g>";
}).join('');
render();
function render() {
let dp = target - pos;
pos += Math.abs(dp) < 1 ? 0 : Math.sign(dp);
let p1 = track.getPointAtLength(pos),
p2 = track.getPointAtLength(pos + 1),
a = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
ship.setAttribute("transform", "translate("+p1.x+","+p1.y+")rotate("+a+")");
requestAnimationFrame(render)
}
let circles = document.querySelectorAll('circle');
circles.forEach(c => c.onclick = e => {
circles.forEach(c1 => c1.parentNode.classList.toggle('active', c===c1))
target = +c.dataset.len;
});<code lang="javascript">
</code>
<code lang="css">
#ship {
fill: #75e3c6;
}
#track {
fill: none;
stroke: #ddedf4;
stroke-width: 6px;
stroke-dasharray: 0 9px;
stroke-linecap: round;
}
circle {
cursor: pointer;
fill: #49a2c7;
stroke-width: 0;
transition: 0.5s;
}
rect {
fill: transparent;
transition: 0.5s;
}
text {
text-anchor: middle;
font-family: Arial;
font-size: 12px;
user-select: none;
}
.active circle {
fill: #e53326;
stroke: #e53326;
stroke-width: 3px;
}
.active rect {
fill: #e53326;
}
.active text {
fill: #ffffff;
}
</code>