JS Color Generator Bit Animation

by Scott Means

HTML

<div id="frame">
    <table>
        <tr>
            <th></th>
            <th colspan="4" style="text-align: left;">msb</th>
            <th colspan="25"></th>
            <th colspan="4" style="text-align: right";>lsb</th>
        </tr>
        <tr id="bitpos">
            <th>&nbsp;</th>
            <th>31</th>
            <th>30</th>
            <th>29</th>
            <th>28</th>
            <th>27</th>
            <th>26</th>
            <th>25</th>
            <th>24</th>
            <th>23</th>
            <th>22</th>
            <th>21</th>
            <th>20</th>
            <th>19</th>
            <th>18</th>
            <th>17</th>
            <th>16</th>
            <th>15</th>
            <th>14</th>
            <th>13</th>
            <th>12</th>
            <th>11</th>
            <th>10</th>
            <th>9</th>
            <th>8</th>
            <th>7</th>
            <th>6</th>
            <th>5</th>
            <th>4</th>
            <th>3</th>
            <th>2</th>
            <th>1</th>
            <th>0</th>
        </tr>
        <tr>
            <th>index bits</th>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit >0</x-bit></td>
            <td><x-bit...

CSS

html, body {
    display: flex;
    flex-direction: column;
    align-items: center;
    font-family: sans-serif;
    font-size: 80%;

    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

#frame {
    width: 100%;
    height: auto;
    display: flex;
    background: white;
    padding: 1rem;
    border-radius: .5em;

    color: black;
}

#frame th {
    color: blue;
}

#bitpos th {
    font-size: 80%;
    transform: rotate(-90deg);
}

td {
    position: relative;
    width: 1em;
}
x-bit {
    position: absolute;
    top: .2em;
    font-family: monospace;
    width: 1em;
    height: auto;
    text-align: center;
}

JavaScript

document.addEventListener('DOMContentLoaded', () => {
    function rgbBitPos(i) {
        i %= 24;
        const c = i % 3;
        const p = Math.floor(i/3);

        return (8-p + c * 8)-1;
    }

    i = 31;

    let css = '';
    const xba = document.querySelectorAll('x-bit');
    const xw = xba[0].clientWidth;

    xba.forEach((el) => {
        if (i < 0) {
            return;
        }

        el.id = `b${i}`;
        
        const np = i < 24 ? rgbBitPos(i) : i;

        const tb = xba[xba.length-np-1];
        const tr = tb.getBoundingClientRect();
        const sr = el.getBoundingClientRect();

        const nx = tr.x-sr.x;
        const ny = tr.y-sr.y;

        css += `
        .animate x-bit#b${i} {
            transform: translate(${nx}px, ${ny}px);
            transition: transform .5s ${.15*i}s;
        }        
        `;

        i--;
    })

    const se = document.createElement('style');
    se.innerHTML = css;

    document.querySelector('head').appendChild(se);

    animateButton.addEventListener('click', (e) => {
        frame.classList.toggle('animate');
    })
})