JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="canvasId" width=500 height=300></canvas>
<div id="triangle_container">
    <span class="triangle"></span>
    <span class="triangle base1"></span>
    <span class="triangle base2"></span>
</div>

CSS

#triangle_container {
    width: 500px;
}
.triangle {
    height: 105px;
    width: 0px;
    background-color: #FFC821;
    position: relative;
    margin: 0px 75px;
    display: block;
    margin: 0px auto;
}
.triangle:before, .triangle:after {
    content: "";
    width: 0;
    height: 0;
    border-bottom: 105px solid #FFC821;
    position: absolute;
    top: 0px;
}
.triangle:before {
    border-left: 75px solid transparent;
    left: -75px;
}
.triangle:after {
    border-right: 75px solid transparent;
    right: -75px;
}
.triangle:hover {
    background-color: #0000FF;
}
.triangle:hover:before {
    border-bottom-color: #0000FF;
}
.triangle:hover:after {
    border-bottom-color: #0000FF;
}
.base1 {
    width: 150px;
}
.base2 {
    width: 300px;
}

JavaScript

var Triangle = function (color, width, height, segments) {  
    var context = document.getElementById("canvasId").getContext("2d");
    
    var slope = height / (width/2);
    this.withinTriangle = function (x, y) {
        // vector 1 (the line)
        var a = [(width/2), -1*height];
        // vector 2 (the point-ish)
        var b = [(width/2) - x, 0 - y];
        // Cross Product
        var inleft = a[0]*b[1]-a[1]*b[0]<=0;
        var inbot = y < height;
        // recalculate a
        a = [(width/2), height];
        var inright = a[0]*b[1]-a[1]*b[0]<=0;
        // Return either segment contained within or false
        return inleft && inbot && inright ? Math.floor(y/(height/segments)) : false;
    };
    
    // 0 count for segments, use withinTriangle return value
    this.highlightSegment = function (seg, clr) {
        // if we're not highlighting a valid segment, don't
        if (seg === false || seg> segments || seg < 0) return;
        // height of segments. Dynamic so that number of segments can be changed on the fly
        var segheight = height / segments;
        
        // Redraw triangle
        this.refill();
        // Clear needed space
        context.clearRect(0,seg*segheight,width,segheight);
        
        // Y val for top pieces
        var topy = (seg)*segheight;
        // Y val for bottom pieces
        var boty = (seg+1)*segheight;
        // X val for top pieces (use width - x for right side)
        var topin = (segments-seg)*segheight/slope;
        // X val for bottom pieces (use width - x for right side)
        var botin = (segments-seg-1)*segheight/slope;
        context.beginPath();
        context.moveTo(botin,boty);
        context.lineTo(topin,topy);
        context.lineTo(width-topin,topy);
        context.lineTo(width-botin,boty);
        context.closePath();
        context.fillStyle = clr;
        context.fill();
    };
    
    // Redraw Triangle
    this.refill = function (clrOvr) {
       ...