html canvas draw straight line

I want to use MS paint style line tool to draw straight line using UI on html canvas element using JS.

The issue is that line preview must be visible on canvas as mouse is being dragged after click at starting position (line preview is basically straight line from starting click point to current mouse position). Once mouse shifts to new position without release, the old line preview should vanish and new one should show. Finally, once mouse is released, the final line should be painted on the canvas. Instead, I get the kind of image you see below.

I tried various ways to perform the following steps in this order but no success:

Repeat until mouse released:

  1. Store current image on canvas.
  2. Paint straight line from starting point to current cursor position.
  3. Restore previous image seen in step #1 on canvas upon detecting mouse movement.
  4. Paint new straight line from starting point to current cursor position.
window.onload = function() {
    const canvas = document.getElementById('paintCanvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
    
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;

    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    let painting = false;
    let startX, startY;
    let canvasState = false;

    canvas.addEventListener('mousedown', startPosition);
    canvas.addEventListener('mouseup', endPosition);
    canvas.addEventListener('mousemove', draw);

    ctx.lineWidth = 5;
    ctx.lineCap = 'round';

    function startPosition(e) {
        painting = true;
        [startX, startY] = [e.offsetX, e.offsetY];
        ctx.save();
        ctx.beginPath();
        draw(e);
    }

    function endPosition() {
        ctx.closePath();
        ctx.restore();
        painting = false;
        canvasState = false;
    }

    function draw(e) {
        if (!painting) return;

        if (selectedTool.id === 'pencil') {
            ctx.lineTo(e.offsetX, e.offsetY);
            ctx.stroke();
        } else if (selectedTool.id === 'line') {
            // write code that works with a line 
            if (e.type === 'mousemove') {
                // remove old preview line
                if (canvasState) {
                    ctx.putImageData(canvasState, 0, 0);
                } else {
                    canvasState = ctx.getImageData(0,0,canvas.width,canvas.height);
                }
                // paint straight line from original start to current mouse position
                ctx.moveTo(startX, startY);
                ctx.lineTo(e.offsetX, e.offsetY);
                ctx.stroke();
            }
        } else if (selectedTool.id === 'eraser') {
            if (e.type === 'mousedown') {
                ctx.strokeStyle = ctx.fillStyle;
                ctx.lineWidth += 5;      
            } else {
                ctx.lineTo(e.offsetX, e.offsetY);
                ctx.stroke();    
            }
        }
    }

};

This is what gets painted on the canvas.