JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>

<div style="float: left;">
    <canvas id="canvas1" width="50" height="50" style="border: 1px solid #000000; float: left;"></canvas>
    <div id="canvas1_info" style="float: left; clear: both;"></div>
</div>
<div style="float: left; clear: both; margin-top: 100px;">
    <canvas id="canvas2" width="1" height="1" style="border: 1px solid #000000; float: left;"></canvas>
    <div id="canvas2_info" style="float: left; clear: both;"></div>
</div>

</body>
</html>

JavaScript

$(document).ready(function() {
    var iters = 32; // Number of stamp iterations.
    var rgba = [127, 0, 0, 2]; // Color to use for stamp iterations.
    
    // Truncate the given value to 4 decimal places without rounding.
    function trunc4(val) {
        return Math.floor(val * 10000) / 10000;
    }
    
    // Stamp the requested color on the canvas the given number of times.
    // At the end of the stamping process, the resulting color is compared
    // to a precise calculated value based on an unmodified Porter-Duff
    // source-over-dest blend function.
    function stampOnCanvas(canvas) {
        var context = canvas.getContext("2d");
        context.globalCompositeOperation = "lighter";
        // Set the fill style to our requested color.
        context.fillStyle = "rgba(" + rgba[0] + "," + rgba[1] + "," + rgba[2] + "," + rgba[3] / 255.0 + ")";
        
        // Maintain an expected, calculated color value based on the custom blend func.
        var calc;
        var calc_old = [0.0, 0.0, 0.0, 0.0];
        var calc_old_noround = [0.0, 0.0, 0.0, 0.0];
        
        // Keep track of each intermediate blend result to watch for rounding errors.
        var trace = "Intermediate values:<br />";
        
        // Stamp the color on the canvas the requested number of times.
        for (var i = 0; i < iters; ++i) {            
            calc = srcOverDstBlend(rgba, calc_old);
            
            var color = context.getImageData(0, 0, 1, 1).data;
            trace += "(" + i + ") | Result: [" + color[0] + ", " + color[1] + ", " + color[2] + ", " + color[3] + "] -|- Expected: ";
            trace += "[" + trunc4(calc_old_noround[0]) + ", " + trunc4(calc_old_noround[1]) + ", " + trunc4(calc_old_noround[2]) + ", " + trunc4(calc_old_noround[3]) + "]<br />";
            
            context.fillRect(0, 0, canvas.width, canvas.height);
            
            // Update trace variables.
            calc_old_noround = calc;
            calc_old =...