JSFiddle - React, Tailwind, and code Playground

by eprouver

HTML

<div ng-app="rm" class="rm" ng-controller="hexmap">
    <div id="fontBase" class="holder">
        <div class="ibws-fix" ng-repeat="r in rows track by $index">
            <div class="hexagon" ng-repeat="h in r track by $index" ng-class="h.prog">
                <div class="hexagontent">
                    <p>&nbsp;</p>
                    <p ng-show="h.curr">
                        <button ng-click="advance(h)" ng-show="h.curr && h.prog && h.prog != 'finished'" ng-disabled="h.prog == 'locked'">Finish</button>
                        <button ng-click="path(h)" ng-show="h.curr.others.length > 0 && !h.help">Help</button>
                    </p>
                </div>
            </div>
        </div>
    </div>
</div>

CSS

body{
    background: #F1F2F5;  
}
.rm{
    -webkit-transform-style: preserve-3d;
    -webkit-perspective: 1316;
}
.holder {
font-size: 10px;
width: 82.5em;
-webkit-transform: rotateX(27deg) translate3d(0, -2704px, 165px);
-webkit-transform-style: preserve-3d;
}
.hexagon {
    position: relative;
    display: inline-block;
    margin: 0.1em 1.8em;
    background: #fff;
    text-align: center;
    -webkit-transition: all 1500ms ease;
}
.hexagon, .hexagon::before, .hexagon::after {
    width: 6.7em;
    height: 11.6em;
    border-radius: 20%/5%;
}
.hexagon::before {
    background-color: inherit;
    content:"";
    position: absolute;
    left: 0;
    transform: rotate(-60deg);
}
.hexagon::after {
    background-color: inherit;
    content:"";
    position: absolute;
    left: 0;
    transform: rotate(60deg);
}
.hexagon:nth-child(even) {
    /* top approx. 50% of .hexagon height + spacing */
    top: 5.9em;
}
.hexanone {
    position: relative;
    display: inline-block;
    width: 6.7em;
    height: 11.6em;
    margin: 0.1em 1.8em;
}
.hexanone:nth-child(even) {
    top: 5.9em;
}
.hexagontent {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 140%;
    line-height: 1.2;
    z-index: 100;
}
.ibws-fix {

}
.hexagon.unlocked {
    background: orange;
    -webkit-transform: translate3d(0, 0, 10px);
}
.hexagon.finished {
    background: rgb(77, 232, 77);
    -webkit-transform: rotateY(360deg) translate3d(0, 0, 20px);
}
.hexagon.path {
    background: rgb(219, 184, 106);
    -webkit-transform: rotateY(180deg) translate3d(0, 0, -10px);
}

.hexagon.locked{
    background:  #ccc;
    -webkit-transform: translate3d(0, 0, 10px);
}

JavaScript

Array.prototype.chunk = function (n) {
    if (!this.length) {
        return [];
    }
    return [this.slice(0, n)].concat(this.slice(n).chunk(n));
};

document.getElementById('fontBase').style.fontSize = window.innerWidth / 600;

angular.module('rm', []).controller('hexmap', function ($scope, $timeout) {
    var currs = Array.apply(null, {
        length: 7
    }).map(function (v, i) {
        return {
            cId: Math.random(),
            others: Array.apply(null, {
                length: ~~ (Math.random() * 10)
            }).map(function (v, i) {
                return {
                    cId: Math.random()
                }
            })
        }
    })


    var progress = {};
    var proglength = Object.keys(progress).length;

    if (proglength === 0) {
        //Add prog for first poi
        progress[currs[0].cId] = 'unlocked';
    }

    currs = currs.reverse();

    var extraRows = 4;

    $scope.rows = Array.apply(null, {
        length: currs.length * 7 * extraRows
    }).map(function (v, i) {
        return {
            loc: i
        }
    }).chunk(7);

    currs.forEach(function (v, i) {
        var r = (extraRows - 2) + i * extraRows;

        v.col = 3;
        v.row = r;
        v.next = currs[i - 1] || 'test';
        $scope.rows[r][3].curr = v;
        $scope.rows[r][3].prog = progress[v.cId];
    });


    $scope.advance = function (h) {
        h.prog = 'finished';
        if(h.curr.next)
        $scope.pathto(h.curr, h.curr.next);
    };

    $scope.pathto = function (me, next) {
        function ani(r, c, a, t) {
            $timeout(function () {
                $scope.rows[r][c].prog = a;
            }, t);
        }

        var now = {
            col: me.col,
            row: me.row
        };
        var go = 0;
        while ((now.col != next.col || now.row != next.row) && go < 10) {
            go++;

            //if (go % 2) {
                if (now.col < next.col) now.col += 1;
                if (now.col >...