JSFiddle - React, Tailwind, and code Playground

DealWithJs logo

by Csaba Hellinger

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.2.4/svg.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.filter.js/2.0.2/svg.filter.min.js"></script>
<div id="svg">    
</div>

CSS

body {
    background: #DDD;
}

svg {
    //background: yellow;
    padding: 20px;
    box-sizing: border-box;
}

.hex {
    fill: transparent;
    stroke: #CCC;
}

.letter {
    fill: pink;
    stroke: red;
    opacity: 0.5;
}

.marker {
    fill: lime;
    opacity: 0.5;
}

JavaScript

const
    rIn = 16,
    rOut = 40,
    wOut = Math.sqrt(3)/2 * rOut,
    wSpace = 5;

function degToRad(deg) {
    return Math.PI / 180 * deg;
}

function hexagon(x, y, r) {
    return [60, 120, 180, 240, 300, 360]
        .map(degToRad)
        .map(rad => ({
            x: x + r * Math.sin(rad),
            y: y + r * Math.cos(rad)
        }));
}

function linePath(points) {
    let data = points.map(point => point.x + ',' + point.y).join(' L ');
    return 'M ' + data + ' Z';
}

const paths = [];
function makePath(index, x, y, r) {
    const data = hexagon(x, y, r),
          path = linePath(data);
    paths[index] = data;    
    return path;
}

// 'A1' -> paths[0][1]
function strToPoint(pointstr) {
    const i1 = pointstr.charCodeAt(0) - 65,
          i2 = Number(pointstr.substring(1));
    return paths[i1][i2]
}

function makeLetter(pathstr) {
    const data = pathstr.split(' ').map(strToPoint);
    draw.path(linePath(data))
    	.addClass('letter')
        .filter(function(add) {
            var blur = add
            	.offset(0, 0)    
                .in(add.sourceAlpha)
                .gaussianBlur(5);
            add.blend(add.source, blur); 
        });
}

function testMarker(pointstr) {
    const p = strToPoint(pointstr);
    draw.circle().move(p.x, p.y).radius(5).addClass('marker');    
}

function makeHexPoints() {
    for (let iX=0; iX<2; iX+=1) {
        const x = (iX * 2 + 1) * wOut + iX*wSpace;
        for (let iY=0; iY<2; iY+=1) {
            const y = iY * (rOut+rIn) + rOut,
                  index = iX*4 + iY*2;
            draw.path(makePath(index,   x, y, rOut)).addClass('hex');
            draw.path(makePath(index+1, x, y, rIn )).addClass('hex');
        }
    }
}

const draw = SVG('svg').size('100%', '100%');

makeHexPoints();
makeLetter('A3 A2 A1 A0 C1 C0 C5 C4 C3 D3 D4 D5 D0 D1 B0 B1 B2 B3');
makeLetter('E0 E1 E2 E3 E4 H1 H0 H5 H4 H3 G3 G4 G5 G0 G1 F4 F3 F2 F1 F0');
//testMarker('A1');

draw.viewbox(0,0,wOut*4 + wSpace, 4*rOut...