JSFiddle - React, Tailwind, and code Playground

by ozzon91

HTML

<div class='area'>
    <div class='block select-none' data-w='2' data-l='100'>A</div>
    <div class='block select-none' data-w='2' data-l='150'>B</div>
    <div class='block select-none' data-w='2' data-l='180'>B</div>
    <div class='center select-none'>Centr</div>
    <canvas id='canvas' width='500px' height='500px'></canvas>
</div>
<span></span>

CSS

body {
    background-color: #D3D3D3;    
}

.area {
    position: relative;
    width: 500px;
    height: 500px;
    margin: auto;
}

.block {
    background-color: orange;
    border-radius: 50%;
    border: 1px #000 solid;
    position: absolute;
    text-align: center;

    margin: -25px 0 0 -25px;
    
    width: 50px;
    height: 50px;
    
    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 {
    border-radius: 50%;
    position: absolute;
    
    top: 250px;
    left: 250px;
    text-align: center;
    
    width: 50px;
    height: 50px;
    
    margin: -25px 0 0 -25px;
    background: #613DBC;
    
    cursor: pointer;
}

JavaScript

var offset,
    margin = 3,
    // кэшируем блок area
    $area = $(".area"),
    // центр области
    center = {
        x: 250,
        y: 250
    },
    // кэшируем центер
    $center = $('.center'),
    // чтобы не было магических цифр, запишем в переменные размер области
    width = 500,
    height = 500,
    // объект который вращаем
    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);
        
        $blocks.each(function() {
            
            $this = $(this);
            // читаем координаты
            x = $this.css('left');
            y = $this.css('top');
            // переводим курсор в центр
            
            ctx.beginPath();
            //задаем ширину линии
            ctx.lineWidth = 1 + 1*$this.data('w');

            ctx.moveTo(center.x, center.y);
            // и от него рисуем линию
            ctx.lineTo(parseFloat(x), parseFloat(y));
            ctx.stroke();
            //рисуем круги
            //ctx.beginPath();
            //ctx.arc(parseFloat(x)-50, parseFloat(y)-250, 15, 0,...