Как можно сделать соединение блоков линией динамически

Есть два блока, нужно при нажатии на один блок, провести до второго блока линию. Как можно это сделать?

Я так понимаю это надо сделать функцию на js и по айдишникам как то определять координаты, и по ним рисовать


Ответы (2 шт):

Автор решения: Danila

Можно обойтись и без js вовсе - нажатие/клик на css обрабатывается с помощью чекбокса или радиобаттона. Другое дело, что по Вашему описанию не очень понятно, как должны располагаться блоки, прямая ли должна быть линия и т.д. Но в самом общем виде решение может быть таким:

.wrapper {
  display: flex;
}
#click {
  display: none;
}
label[for="click"] {
  display: block;
  width: 30%;
  padding: 20px;
  text-align: center;
  border: 1px solid red;
}
.line {
  width: 40%;
  position: relative;
}
.line:before {
  content: '';
  display: block;
  position: absolute;
  height: 1px;
  width: 0;
  left: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  background-color: blue;
  transition: 1s;
}
#click:checked ~ .line:before {
  width: 100%;
}
.target {
  width: 30%;
  padding: 20px;
  border: 1px solid green;
}
<div class="wrapper">
  <input type="checkbox" name="check" id="click">
  <label for="click">Кликни</label>
  <div class="line"></div>
  <div class="target"></div>
</div>

→ Ссылка
Автор решения: ΝNL993

Если ваша линия должна проходить прямо и по горизонтали то вот:

a.addEventListener('click', e => {
  let e_bcr = e.target.getBoundingClientRect()
  let b_bcr = b.getBoundingClientRect()
  line.style.top = e_bcr.bottom / 2 + 'px'
  line.style.left = e_bcr.width + e_bcr.left + 'px'
  line.style.width = b_bcr.x - e_bcr.x - e_bcr.width + 'px'
}, {once: true})
div {
  float: right;
  border: 1px solid black;
  padding: .5rem;
}

#a {
  float: left;
}

#line {
  background: black;
  position: absolute;
  transition: 1s linear;
  height: 1px;
  padding: 0;
  margin: 0;
  border: 0;
}
<div id="a">Нажми на меня!</div>
<div id="b">Какой-то Блок</div>
<div id="line" style="width: 0;"></div>

P.S. лично мне больше понравился ответ от @Danila.

→ Ссылка