JSFiddle - React, Tailwind, and code Playground

HTML

<title>JS fractals</title>
<body>

    <div class="container">
        <canvas id="drawfrac" width="600px" height="600px"></canvas>

        <table class="table">
        <tr>
        <td class="baseprop">
            <div class="title">Baseline</div>
            <input id="showbase" name="show" type="checkbox" checked>Show<br>
            Normal color: <input id="basenormcolor" name="ncolor" type="text" value="#000080"><br>
            Inverse color: <input id="baseinvcolor" name="icolor" type="text" value="#800000"><br>
            Line width: <input id="basewidth" name="bwidth" type="text" value="2"><br>
            Background: <input id="backcolor" name="bcolor" type="text" value="#D0D0D0"><br>
        </td>
        <td class="fracprop">
            <div class="title">Fractal</div>
            <input id="showfrac" name="show" type="checkbox" checked>Show<br>
            Fractal iterations:
            <select id="fracdepth">
            <option value="0">0</option>
            <option value="1">1</option>
            <option value="2" selected>2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
            <option value="-1">as needed</option>
            </select><br>
            Fractal color: <input id="fraccolor" name="fcolor" type="text" value="#40F040"><br>
            Line width: <input id="fracwidth" name="fwidth" type="text" value="2"><br>
        </td>
        </tr>
        <tr>
        <td class="description" colspan="2">
            <div class="title">Description</div>
            A simple JS program to draw a simplest type of fractals. Use:<br>
            <i>Shift + Left Click on baseline segment</i> to add node to baseline;<br>
            <i>Ctrl + Left Click on baseline node</i> to remove node;<br>
            <i>Left Click on node</i> to move node;<br>
            <i>Left Click on segment</i> to reverse fractal on that segment;<br>
            <i>Left Click on...

CSS

.container {
        width: 680px;
        margin: 20px;
    }
    #drawfrac {
        margin: 40px;
        border: 2px solid black;
    }
    .table {
        width: 100%;
        border-spacing: 5px;
        line-height: 170%;
    }
    .baseprop, .fracprop {
        width: 50%;
        background-color: #F0F0C0;
        border: 1px solid black;
        padding: 0 10px;
        vertical-align: top;
    }
    .description {
        background-color: #C0F0C0;
        border: 1px solid black;
        padding: 0 10px;
    }
    .title {
        text-align: center;
        font-weight: bold;
    }

JavaScript

// Функция, которая создает объект фрактала. Здесь происходит вычисление фрактала,
// отрисовка и изменения. Странно работать с этими объектами JS без классов.
function fracObject() {

    // Здесь будут приватные данные и методы.
    var own = {};
    // А здесь публичные.
    var that = {};

    // Базовая линия, на основе которой строится фрактал.
    own.baseline = [ { x: 50, y: 450 }, { x: 550, y: 450 } ];
    // Нормализованная базовая линия. Первая точка = (0, 0), последняя = (1, 0).
    own.normalized = [];
    // Глубина фрактала. При значении 0 фрактальная кривая соответствует базовой линии.
    // При значении 1 каждый сегмент базовой линии заменяется на копию базовой линии,
    // соответствующим образом смасштабированную и повернутую. При значении 2, это
    // происходит дважды, и так далее. При значении -1 преобразования происходят до тех
    // пор, пока отрезки не станут слишком маленькими.
    own.fracDepth = 0;
    // Вектор inverse[0] определяет заменяется ли сегмент на копию базовой линии (при
    // значении 0), либо на отраженную вдоль оси y копию (при значении 1). Вектор
    // inverse[1] = 1 - inverse[0], исключительно для удобства, векторизации не
    // хватает. И пожалуй, inverse - не лучшее название.
    own.inverse = [ [ 0 ], [ 1 ] ];

    // Нормализация. Масштабирование и поворот, ничего сложного.
    own.normalize = function() {
        own.normalized = [];
        var i, x, y, n = own.baseline.length;
        var x0 = own.baseline[0].x, y0 = own.baseline[0].y;
        var x1 = own.baseline[n-1].x, y1 = own.baseline[n-1].y;
        var d = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
        var a = Math.atan2(y1 - y0, x1 - x0);
        for (i = 0; i < n; i++) {
            x = (own.baseline[i].x - x0) / d;
            y = (own.baseline[i].y - y0) / d;
            own.normalized.push({ x: x * Math.cos(a) + y * Math.sin(a),
                y: y * Math.cos(a) - x * Math.sin(a) });
        }
    };

    // И сразу же...