JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>2点間の線</title>
    <style>
        h1 { font-size: 1.5em; }
        .container {
            display: grid;
            grid-template-columns: fit-content(100%) fit-content(100%);
            gap: 5em;
            position: relative;
        }

        .box {
            width: 10em;
            padding: 1em;
            display: flex;
            flex-direction: column;
            gap: 1em;
        }

        .box > div {
            width: 100%;
            height: 3em;
            cursor: pointer;
        }

        .box > div.active {
            border: solid 4px #888;
        }

        .a {
            background-color: #f44
        }

        .b {
            background-color: #0ff
        }

        .c {
            background-color: #0f0
        }

        .connect-line {
            height: 0.25em;
            background-color: #888;
            position: absolute;
            transform-origin: top left;
        }
    </style>
    <script>
    /**
     * ある要素を原点とした時の要素の座標
     */
    const getPosFromOriginEl = (origin, tgt) => {
        const originRect = origin.getBoundingClientRect();
        const originX = originRect.left;
        const originY = originRect.top;
        const tgtRect = tgt.getBoundingClientRect();
        return {
            left: tgtRect.left - originX,
            top: tgtRect.top - originY,
            right: tgtRect.right - originX,
            bottom: tgtRect.bottom - originY,
            center: {
                x: (tgtRect.right + tgtRect.left) / 2 - originX,
                y: (tgtRect.top + tgtRect.bottom) / 2 - originY,
            },
        };
    };

    /**
     * ある要素の右端の中点からある要素の左端の中点までの相対座標
     * @param from
     * @param to
     * @param origin
     * @return {{top: number, len: number, left: number, deg: number}}
     */
    const getLineA2B = (from, to, origin) => {
        origin = origin ?? document.body;
        const fromPos =...