Как правильно нарисовать линию от одного элемента к другому
Не могу никак разобраться с задачей рисования линии от одного элемента до другого:
const canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
one = document.getElementById('one'),
two = document.getElementById('two');
ctx.beginPath();
ctx.moveTo(one.getBoundingClientRect().left, two.getBoundingClientRect().left);
ctx.lineTo(one.getBoundingClientRect().top, two.getBoundingClientRect().top);
ctx.stroke();
#one, #two{width:10px;height:10px;position:absolute;background:#000;}
#one{top:40px;}
#two{left:50px;top:10px;}
<canvas id="canvas"></canvas>
<span id="one"></span>
<span id="two"></span>
То есть по факту, нужно четко рисовать от одно центра элемента к другому, чтобы линия не разрывалась, но я не могу никак врубиться как мне эти точки найти и расстояние, точек может быть много и нужно, чтобы они от одной начинали двигаться и до последней одной линией.
Как можно так написать цикл, чтобы точек могло быть много.
Выручайте народ, никак не могу врубиться.
Ответы (1 шт):
Как это сделать? Очень просто:
// инструменты для рисования
const ctx = canvas.getContext('2d')
// устанавливаем размеры равные ширине и высоте окна
canvas.width = innerWidth
canvas.height = innerHeight
// получаем размеры и координаты блоков
const one_rect = one.getBoundingClientRect()
const two_rect = two.getBoundingClientRect()
ctx.beginPath()
ctx.moveTo(
// от цента квадрата
one_rect.left + one_rect.width/2,
one_rect.top + one_rect.height/2,
)
ctx.lineTo(
// к центру другого квадрата
two_rect.left + two_rect.width/2,
two_rect.top + two_rect.height/2,
)
ctx.stroke()
body {
margin: 0;
}
#one, #two{
width: 10px;
height: 10px;
position: absolute;
background: #000;
}
#one {
top: 40px;
left: 100px;
}
#two {
left: 250px;
top: 150px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
<span id="one"></span>
<span id="two"></span>
Но тут есть один не очевидный момент: в примере выше я у body убрал стандартный margin, который равен 8px, что будет если его вернуть?
const ctx = canvas.getContext('2d')
// устанавливаем размеры равные ширине и высоте окна
canvas.width = innerWidth
canvas.height = innerHeight
// получаем размеры и координаты блоков
const one_rect = one.getBoundingClientRect()
const two_rect = two.getBoundingClientRect()
ctx.beginPath()
ctx.moveTo(
// от цента квадрата
one_rect.left + one_rect.width/2,
one_rect.top + one_rect.height/2,
)
ctx.lineTo(
// к центру другого квадрата
two_rect.left + two_rect.width/2,
two_rect.top + two_rect.height/2,
)
ctx.stroke()
#one, #two{
width: 10px;
height: 10px;
position: absolute;
background: #000;
}
#one {
top: 40px;
left: 100px;
}
#two {
left: 250px;
top: 150px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
<span id="one"></span>
<span id="two"></span>
Мы всё также с помощью getBoundingClientRect получаем размеры и координаты блоков, но написав context.moveTo(x, y) - мы передвигаемся к этой точке не от левого верхнего угла окна браузера, а от левого верхнего угла канваса. Чтобы решить эту проблему, можно от полученных координат просто вычесть margin.
const ctx = canvas.getContext('2d')
// устанавливаем размеры равные ширине и высоте окна
canvas.width = innerWidth
canvas.height = innerHeight
// получаем размеры и координаты блоков
const one_rect = one.getBoundingClientRect()
const two_rect = two.getBoundingClientRect()
ctx.beginPath()
ctx.moveTo(
// от цента квадрата
one_rect.left + one_rect.width/2 - 8, // <--
one_rect.top + one_rect.height/2 - 8, // <--
)
ctx.lineTo(
// к центру квадрата
two_rect.left + two_rect.width/2 - 8, // <--
two_rect.top + two_rect.height/2 - 8, // <--
)
ctx.stroke()
#one, #two{
width: 10px;
height: 10px;
position: absolute;
background: #000;
}
#one {
top: 40px;
left: 100px;
}
#two {
left: 250px;
top: 150px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
<span id="one"></span>
<span id="two"></span>