JSFiddle - React, Tailwind, and code Playground

by Retsam19

HTML

<canvas id="canvas" width="500" height="400"></canvas>

JavaScript

(function() {
    "use strict";
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    
    ctx.lineWidth = 3;
    
    var SLOPE_COMBINE_TOLERANCE = .1;
    
    var isPenDown = false;
    var lastPos = null;
    
    //Math utils
    function average(values) {return values.reduce(function(a, b) {return a+b},0)/values.length}
    
    //Position utils - drawing
    function moveToPos(pos) {ctx.moveTo(pos.x, pos.y)};
    function lineToPos(pos) {ctx.lineTo(pos.x, pos.y)};
    //Position utils - math
    function d2Between(pos1, pos2) {
        var dx = pos1.x - pos2.x;
        var dy = pos1.y - pos2.y;
        return dx*dx + dy*dy
    }
    
    var lineCount = 0;
    var previousPaths = [];
    var currentPath = [];
    
    function draw(e) {
        var pos = getMousePos(canvas, e);
        if(isPenDown) {
            currentPath.push(pos);
            ctx.strokeStyle = getRandomColor();
            ctx.beginPath();
                moveToPos(lastPos);
                lineToPos(pos);
            ctx.stroke();
        }
        lastPos = pos;
    }
    
    function repaint() {
        canvas.width = canvas.width;
        previousPaths.forEach(drawPath);
    }
    
    function drawPath(path) {
        var positions = path;
        ctx.strokeStyle = getRandomColor();
        ctx.fillStyle = ctx.strokeStyle;
        ctx.beginPath();
        positions.forEach(lineToPos);
        ctx.stroke();
    }
    
    function endPath() {
        var circleScore = scoreAsCircle(currentPath);
        if(circleScore > 0) {
            previousPaths.push(currentPath.concat(currentPath[0])); //close the circle
        }
        currentPath = [];
        repaint();
    }
    
    function scoreAsCircle(currentPath) {
        var positions = currentPath;
        
        //Check start and end points are sufficiently close
        var startPos = positions[0];
        var endPos = positions[positions.length - 1];
        var startEndDist2 =...