JSFiddle - React, Tailwind, and code Playground
HTML
<div class='area'>
<div class='block A select-none' data-l='100'>A</div>
<div class='block B select-none' data-l='150'>B</div>
<div class='block C select-none' data-l='200'>C</div>
<div class='center'></div>
<canvas id='canvas' width='400px' height='400px'></canvas>
</div>
CSS
.area {
position: relative;
width: 400px;
height: 400px;
margin: auto;
}
.block {
position: absolute;
margin: -10px 0 0 -10px;
text-align: center;
width: 20px;
height: 20px;
border: 1px solid #333;
cursor: pointer;
}
.select-none {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.center {
position: absolute;
top: 197px;
left: 197px;
width: 10px;
height: 10px;
margin: -3px 0 0 -3px;
border-radius: 6px;
border: 1px solid #333;
background: #F00;
cursor: pointer;
}
JavaScript
//используем jquery для работы с DOM,
//с ним удобней без него чуть больше кода получится
// смещение блока area относительно левого верхнего угла
// обновляется вовремя mousedown
var offset,
margin = 3,
// кэшируем блок area
$area = $(".area"),
// центр области
center = {
x: 200,
y: 200
},
// кэшируем центер
$center = $('.center'),
// чтобы не было магических цифр, запишем в переменные размер области
width = 400,
height = 400,
// объект который вращаем
target,
// тута запоминаем document, чтобы каждый раз не создавать объект
// ибо события up|move вешаются на него
$doc = $(document),
// контекст работы с канвас
ctx,
// сразу создаем коллекцию блоков, чтобы каждый раз их не искать
$blocks = $('.block');
var // функция инициализации, в случайном порядке раставляем блоки
init = function() {
$blocks.each(function() {
var $this = $(this),
// получаем длинну
l = $this.data('l'),
// берем произвольный угол
angle = Math.round(Math.random()*360);
$this.css({
top: l*Math.cos(Math.PI * angle / 180) + center.y,
left: l*Math.sin(Math.PI * angle / 180) + center.x
});
});
},
// обновляем канвас
update = function() {
var x, y;
// очищаем его сначала, есть какой-то другой способ, но не вспомнил =-)
ctx.clearRect(0,0,width,height);
ctx.beginPath();
$blocks.each(function() {
$this = $(this);
// читаем координаты
x = $this.css('left');
y = $this.css('top');
// переводим курсор в центр
ctx.moveTo(center.x, center.y);
// и от него рисуем линию
ctx.lineTo(parseFloat(x), parseFloat(y));
});
ctx.stroke();
},
//после отпускания левой кнопки...