JSFiddle - React, Tailwind, and code Playground

by Sergei Sokolov

HTML

<canvas id="canvas" width="250" height="125"></canvas>
<section></section>

CSS

canvas {border: 1px solid #CCC}

JavaScript

/**
 * для вопроса https://qna.habr.com/q/957017
 * Как нарисовать линию с кругами на canvas?
 */
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const A = [10, 72];
const B = [240, 72];

const segment = (a, b) => {
  ctx.beginPath();
  ctx.moveTo(...a);
  ctx.lineTo(...b);
  ctx.stroke();
}

const params = {}

const render = () => {
  // очистить холст
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // синяя сплошная
  ctx.strokeStyle = "blue";
  ctx.lineWidth = 5;
  ctx.lineCap = "butt";
  ctx.setLineDash([]);
  segment(A, B);

  // красные точки
  ctx.strokeStyle = "red";
  ctx.lineWidth = params.radius;
  ctx.lineCap = "round";
  ctx.setLineDash([0, params.space]);
  ctx.lineDashOffset = params.offset;
  segment(A, B);
}

// ползунки!
const addSlider = (name, title, min, max, initial) => {
  const div = document.createElement('div');
  const input = document.createElement('input');
  input.type = 'range';
  input.id = `sl-${name}`;
  input.min = min;
  input.max = max;
  input.value = initial;

  const label = document.createElement('label');
  label.for = input.id;
  label.textContent = title;

  div.appendChild(input);
  div.appendChild(label);

  document.querySelector('section').appendChild(div);

  params[name] = initial;

  input.addEventListener('input', (e) => {
    params[name] = +e.target.value;
    render();
  })
}

addSlider('space', 'расстояние', 20, 100, 50);
addSlider('offset', 'смещение', -50, 50, 10);
addSlider('radius', 'размер', 5, 50, 20);

render();