JSFiddle - React, Tailwind, and code Playground

by halflling

HTML

<canvas id="bezier" width="800" height="400" style=""></canvas><br />
Добавить точку - ctrl + click <br />
Удалить точку - shift + click <br />
<br />
Добавить линию - alt + click <br />
Точки можно перемещать. <br />

CSS

#bezier
{
    border-width: 1px;
    border-style: solid;
    background: #FAFAFA;
}

JavaScript

/*
    bezier edit
*/
var pArr = []; // Массив линий
var ctx; // Объект для рисования getContext('2d')
var canvas = document.getElementById('bezier');
var cpt; // Объект указывает на индекс текущей линии (.line), точки (.point) на ней и действие (.isMove)
var pointRadius = 5; // Радиус точкек кривой

// i - номер вершины, n - количество вершин, t - положение кривой (от 0 до 1)
function getBezierBasis(i, n, t) {
    // Факториал
    function f(n) {
        return (n <= 1) ? 1 : n * f(n - 1);
    }
    
    // считаем i-й элемент полинома Берштейна
    return (f(n)/(f(i)*f(n - i)))* Math.pow(t, i)*Math.pow(1 - t, n - i);
}

// arr - массив опорных точек. Точка - двухэлементный массив, (x = arr[0], y = arr[1])
// step - шаг при расчете кривой (0 < step < 1), по умолчанию 0.01. Чем больше шаг - тем грубее кривая
function getBezierCurve(arr, step) {
    if (step === undefined) {
        step = 0.01;
    }
    
    var res = [];
    
    step = step / arr.length;
    
    for (var t = 0.0; t < 1 + step; t += step) {
        if (t > 1) {
            t = 1;
        }
        
        var ind = res.length;
        
        res[ind] = new Array(0, 0);
        
        for (var i = 0; i < arr.length; i++) {
            var b = getBezierBasis(i, arr.length - 1, t);
            
            res[ind][0] += arr[i][0] * b;
            res[ind][1] += arr[i][1] * b;
        }
    }
    
    return res;
}

// Рисуем непрерывную кривую безье
// ctx - rendering context холста
// arr - массив точек по которым строим кривую
// delay - задержка перед отрисовкой следующей точки, pause - пауза перед началом  рисования,
function drawLines(ctx, arr, delay, pause) {
    if (delay === undefined) {
        delay = 10;
    }
    
    if (pause === undefined) {
        pause = delay;
    }
    var i = 0;

    function delayDraw() {
        if (i >= arr.length - 1) {
            return;
        }
        
        ctx.moveTo(arr[i][0],arr[i][1]);
        ctx.lineTo(arr[i+1][0],arr[i+1][1]);
      ...