JSFiddle - React, Tailwind, and code Playground

HTML

<script src=" https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
<svg id="svg"></svg>

JavaScript

function Board (width, height) {
    this.width = width;
    this.height = height;
    this.board = [];
    this.pieces = [];
    for (var y = 0; y < this.height; y++) {
        for (var x = 0; x < this.width; x++) {
            if (!this.board[y]) {
                this.board[y] = [];
            }
            this.board[y][x] = null;
        }
    }

    this.isPieceGrounded = function(piece, testedPieces) {
        var at = { x: piece.getPosition().x, y: piece.getPosition().y+1 };
        if (piece.getHeight()+at.y+1 >= this.height) {
            return true;
        }
        for (var y = 0; y < piece.getHeight(); y++) {
            for (var x = 0; x < piece.getWidth(); x++) {
                if (!piece.shape[y][x]) continue;
                var pieceAtPos = this.board[y+at.y][x+at.x];
                if (pieceAtPos && pieceAtPos!==piece && testedPieces.indexOf(pieceAtPos) < 0) {
                    testedPieces.push(pieceAtPos);
                    if (this.isPieceGrounded(pieceAtPos, testedPieces)) {
                        return true;
                    };
                }
            }
        }
        return false;
    }
    
    this.canPlace = function(piece, at) {
        if (piece.getHeight()+at.y > this.height) {
            return false;
        }
        for (var y = 0; y < piece.getHeight(); y++) {
            for (var x = 0; x < piece.getWidth(); x++) {
                if (!piece.shape[y][x]) continue;
                var pieceAtPos = this.board[y+at.y][x+at.x];
                if (pieceAtPos && pieceAtPos!==piece && this.isPieceGrounded(pieceAtPos, [piece]) ){
                    return false;
                }
            }
        }
        return true;
    }

    this.hasFullLine = function(line) {
        for (var x = 0; x < this.width; x++) {
            if (!this.board[line][x]) {
                return false;
            }
        }
        return true;
    }

    this.place = function(piece) {
        var position =...