JSFiddle - React, Tailwind, and code Playground

HTML

<div class="page">

		<div class="canvas-wrapper">
			<div class="blister-canvas-foreground"></div>
			<canvas id="canvas" width="700" height="550"></canvas>
		</div>
    
		<p>
			<button class="save-canvas">save</button>
			<button class="toggle-zoom">toggle zoom</button>
			<img src="" alt="" class="result" style="display: block;">
		</p>
    
	</div>

CSS

* {
		margin: 0;
		padding: 0;
		box-sizing: border-box;
	}

	.page {
		width: 700px;
		max-width: 100%;
		margin: 20px auto;
	}

	.canvas-wrapper {
        width: 100%;
	    height: 550px;
	    margin: 20px auto;
	    position: relative;
	    border: 1px dashed rgba(0,0,0,.25);
	    border-radius: 5px;
	    background: #fff;
	}

	.blister-canvas-foreground {
	    width: 500px;
	    height: 325px;
	    position: absolute;
	    top: 50%;
	    transform: translateY(-50%);
	    left: 0;
	    right: 0;
	    margin: 0 auto;
	    overflow: hidden;
	    border-radius: 22px;
	    z-index: 1;
      	border: 2px solid;
	}

	.canvas-wrapper.zoomed {
		zoom: .7;
	}

	#canvas {
	    position: relative;
	    z-index: 2;
	    cursor: move;
	    height: 550px;
	}

	.result {
	    width: 500px;
	    height: 325px;
	    margin: 20px auto;
	    border: 2px solid;
	    border-radius: 22px;
	}

	p { text-align: center; }

JavaScript

/*
    vars
     */
    var $jqueryCanvas = $('#canvas');
    var $zoomToggler = $('.toggle-zoom');

    var canvas = document.getElementById('canvas'),
        canvasContext = canvas.getContext('2d'),
        canvasOffset = canvas.getBoundingClientRect(),
        offsetX = canvasOffset.left,
        offsetY = canvasOffset.top,
        startX,
        startY,
        imageX = 50,
        imageY = 50,
        imageWidth,
        imageHeight,
        imageRatio,
        imageRight,
        imageBottom,
        draggingImage = false;

    /*
    user image
     */
    var userImage = new Image();
    userImage.onload=function(){

        imageWidth = userImage.width;
        imageHeight = userImage.height;
        imageRatio = imageWidth / imageHeight;

        imageRight = imageX + imageWidth;
        imageBottom = imageY + imageHeight;

        drawCustomImage(true, false, 0.5);

    }

    userImage.setAttribute('crossOrigin', 'anonymous');
    userImage.src = 'https://c2.staticflickr.com/6/5683/25362817639_ca87842e85_z.jpg';

    /*
    draw blister image
     */
    function drawCustomImage(clearCanvas, withTransparency, opacity){

        var toClear = clearCanvas || true;
        var hasOpacity = withTransparency || false;
        var imageOpacity = opacity || 0.5;

        /*
            clear canvas
        */
        if ( toClear ) resetCanvas();

        /*
            set opacity
        */
        if ( hasOpacity ) canvasContext.globalAlpha = imageOpacity;

        /*
        draw image and reset opacity
         */
        canvasContext.drawImage(userImage, 0, 0, userImage.width, userImage.height, imageX, imageY, imageWidth, imageHeight);
        canvasContext.globalAlpha = 1;

    }

    /*
    clear canvas
     */
    function resetCanvas() {

        canvasContext.clearRect(0, 0, canvas.width, canvas.height);

    }

    /*
    check if image is clicked
     */
    function hitImage(x, y) {

        return ( x > imageX && x < (imageX + imageWidth)...