I
I
Ilya2019-08-11 05:58:00
JavaScript
Ilya, 2019-08-11 05:58:00

Clicks on the COUNT variable should be remembered. How to do it?

There is a curve and there are points on it, and there is one boat. The challenge is to make clicks by year memorable. Those. when clicking 2001 -> 2005 -> 2002, the ship should "sail" from 2001 to 2005 and return to 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>

5d4f84a14825e995736954.jpeg

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
RAX7, 2019-08-11
@lucker_scott

By clicking on the label, add data-len to the array and slightly change the logic of the render ()

K
kr_ilya, 2019-08-11
@kr_ilya

Alternatively, store in local storage.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question