JSFiddle - React, Tailwind, and code Playground

HTML

<script src="jquery.js"></script>
<script src="jquery.jqpuzzle.js"></script>
<link rel="stylesheet" href="jquery.jqpuzzle.css">
<script src="jquery-ui.js"></script>
<script src="jqPuzzle jqp-r3-c5-h5"></script>
<title>Shuffle Picture Game</title>
<img src="http://lackeyinnovations.azurewebsites.net/images/mountain.jpg" alt="Mountain" class="jqPuzzle jqp-r3-c5-h5"></img>

CSS

.jqPuzzle {
    padding: 5px;
    border: 1px solid #222222;
    background-color: #DDDDFF;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}
.jqPuzzle div {
    background-color: transparent;
    margin: 0px;
    padding: 0px;
    border-style: none;
}
/* div wrapper which holds the puzzle pieces and the solution image */
 .jqPuzzle .jqp-wrapper {
    padding: 2px;
    border: 1px solid #FFFFFF;
    background-color: #444455;
}
.jqPuzzle .jqp-piece {
    border: 1px solid #FFFFFF;
    color: #FFFFFF;
    font-size: 36px;
}
.jqPuzzle .jqp-piece:hover {
    border-style: dashed;
}
.jqPuzzle.jqp-solved .jqp-piece:hover {
    border-style: solid;
}
.jqPuzzle .jqp-controls {
    float: left;
}
.jqPuzzle .jqp-controls a {
    margin-top: 5px;
    margin-right: 8px;
    padding: 3px 5px;
    border: 1px outset #FFFFFF;
    background-color: #777799;
    color: #FFFFFF;
    font-size: 14px;
    line-height: normal;
    float: left;
}
.jqPuzzle .jqp-controls a:hover {
    background-color: #7777BB;
}
.jqPuzzle .jqp-controls a.jqp-toggle, .jqPuzzle .jqp-controls a.jqp-down {
    padding-left: 4px;
    padding-right: 6px;
    border-style: inset;
    background-color: #BBBBFF;
}
.jqPuzzle .jqp-controls a.jqp-disabled {
    background-color: #DDDDEE;
    color: #FFFFFF;
}
.jqPuzzle .jqp-controls span {
    margin-top: 5px;
    padding: 2px 4px;
    padding-left: 0px;
    border: none;
    background-color: transparent;
    color: #666666;
    font-size: 14px;
    float: left;
}
/ .jqPuzzle .jqp-controls span.jqp-disabled {
    color: #AAAAAA;
}
.jqPuzzle.jqp-solved .jqp-controls span {
    padding: 1px 3px;
    border: 1px dotted #0F8F08;
    background-color: #9FEF86;
    color: #0F8F08;
}
.jqPuzzle .jqp-controls span input {
    margin: 0px 3px;
    padding: 3px;
    padding-bottom: 2px;
    border-style: none;
    background-color: #FFFFFF;
    color: #666666;
    font-weight: bold;
    text-align: right;
}
.jqPuzzle .jqp-controls span.jqp-disabled input {
   ...

JavaScript

function imageBlock(no, x, y) {

    this.no = no;
    this.x = x;
    this.y = y;
    this.isSelected = false;
}

function SetImageBlock() {

    var total = TOTAL_PIECES;
    imageBlockList = new Array();
    blockList = new Array();

    var x1 = BLOCK_IMG_WIDTH + 20;
    var x2 = canvas.width - 50;
    var y2 = BLOCK_IMG_HEIGHT;

    for (var i = 0; i < total; i++) {

        var randomX = randomXtoY(x1, x2, 2);
        var randomY = randomXtoY(0, y2, 2);

        var imgBlock = new imageBlock(i, randomX, randomY);

        imageBlockList.push(imgBlock);

        var x = (i % TOTAL_COLUMNS) * BLOCK_WIDTH;
        var y = Math.floor(i / TOTAL_COLUMNS) * BLOCK_HEIGHT;

        var block = new imageBlock(i, x, y);
        blockList.push(block);

    }

}

function drawAllImages() {

    for (var i = 0; i < imageBlockList.length; i++) {
        var imgBlock = imageBlockList[i];
        if (imgBlock.isSelected == false) {

            drawImageBlock(imgBlock);
        }
    }
}

function drawImageBlock(imgBlock) {

    drawFinalImage(imgBlock.no, imgBlock.x, imgBlock.y, BLOCK_WIDTH, BLOCK_HEIGHT);

}

function drawFinalImage(index, destX, destY, destWidth, destHeight) {

    ctx.save();

    var srcX = (index % TOTAL_COLUMNS) * IMG_WIDTH;
    var srcY = Math.floor(index / TOTAL_COLUMNS) * IMG_HEIGHT;

    ctx.drawImage(image1, srcX, srcY, IMG_WIDTH, IMG_HEIGHT, destX, destY, destWidth, destHeight);

    ctx.restore();
}
canvas.onmousedown = handleOnMouseDown;
canvas.onmouseup = handleOnMouseUp;
canvas.onmouseout = handleOnMouseOut;
canvas.onmousemove = handleOnMouseMove;

function handleOnMouseDown(e) {

    // remove old selected
    if (selectedBlock != null) {

        imageBlockList[selectedBlock.no].isSelected = false;

    }

    selectedBlock = GetImageBlock(imageBlockList, e.pageX, e.pageY);

    if (selectedBlock) {
        imageBlockList[selectedBlock.no].isSelected = true;
    }

}

function handleOnMouseMove(e) {

    if (selectedBlock) {

       ...