JSFiddle - React, Tailwind, and code Playground

HTML

<img class="jqPuzzle" src="https://pp.vk.me/c308916/v308916649/a18f/YRSSDhyEa1g.jpg">

CSS

/*
 * jqPuzzle - Sliding Puzzles with jQuery
 * Default CSS theme
 * 
 * Copyright (c) 2008 Ralf Stoltze, http://www.2meter3.de/jqPuzzle/
 * Dual-licensed under the MIT and GPL licenses.
 *
 * Note that some CSS properties are set by the jqPuzzle script itself to make 
 * sure that the puzzle works properly. These properties will overwrite 
 * user-defined properties.
 * 
 * The class 'jqp-solved' is added to the outermost element when a puzzle is 
 * solved by the user. Use '.jqPuzzle.jqp-solved' to define different styles
 * for solved puzzles.
 */

/* outermost element which holds the full puzzle interface */
.jqPuzzle {
	padding: 5px;
	border: 1px solid #222222;
	background-color: #DDDDFF;
	font-family: Verdana, Arial, Helvetica, sans-serif;
}

/* only needed if external css rules set defaults for divs,
   this rule only resets the most common properties */
.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;
}

/* a single puzzle piece */
.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;
}

/* the controls area which holds the buttons and the display */
.jqPuzzle .jqp-controls {
	float: left;
}

/* a button */
.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;
}

/* toggle/down state for buttons */
.jqPuzzle .jqp-controls a.jqp-toggle, 
.jqPuzzle .jqp-controls a.jqp-down {
	padding-left: 4px;
	padding-right: 6px;
	border-style: inset;
	background-color: #BBBBFF;
}

/*...

JavaScript

(function($) {
/*
 * jqPuzzle - Sliding Puzzles with jQuery
 * Version 1.02
 * 
 * Copyright (c) 2008 Ralf Stoltze, http://www.2meter3.de/jqPuzzle/
 * Dual-licensed under the MIT and GPL licenses.
 */
$.fn.jqPuzzle = function(settings, texts) {

	// default settings
	var defaults = {
		
		rows: 4, 					// number of rows [3 ... 9]
		cols: 4,		 			// number of columns [3 ... 9]
		hole: 16,					// initial hole position [1 ... rows*columns]
		shuffle: false,				// initially show shuffled pieces [true|false]
		numbers: true,				// initially show numbers on pieces [true|false]
		language: 'en',				// language for gui elements [language code]
		
		// display additional gui controls
		control: {
			shufflePieces: true,	// display 'Shuffle' button [true|false]
			confirmShuffle: true,	// ask before shuffling [true|false]
			toggleOriginal: true,	// display 'Original' button [true|false]
			toggleNumbers: true,	// display 'Numbers' button [true|false]
			counter: true,			// display moves counter [true|false]
			timer: true,			// display timer (seconds) [true|false]
			pauseTimer: false		// pause timer if 'Original' button is activated 
									// [true|false]
		},
		
		// perform actions when the puzzle is solved sucessfully
		success: {
			fadeOriginal: true,		// cross-fade original image [true|false]
			callback: undefined,	// callback a user-defined function [function]
									// the function is passed an object as its argument
									// which includes the fields 'moves' and 'seconds'
			callbackTimeout: 300	// time in ms after which the callback is called
		},		
		
		// animation speeds and settings
		animation: {
			shuffleRounds: 3,		// number of shuffle rounds [1 ... ]
			shuffleSpeed: 800,		// time in ms to perform a shuffle round
			slidingSpeed: 200,		// time in ms for a single move
			fadeOriginalSpeed: 600	// time in ms to cross-fade original image
		},
		
		// additional style information not specified via css
		style: {
			gridSize: 2,			// space between...