Search code examples
javascriptjqueryhtmlcanvaszooming

Reset zoom & rotation values to zero Onclick Button


Background :

User click on Mask & upload their own image on the mask.

Once image uploaded, Edit button is displaying on the image.

enter image description here

Once user click on Edit Text, we are displaying pop up box.

Clik on Zoom or Rotate buttons....

enter image description here

Click on Remove button & upload new image....

Issue :

Now image will display in same position as old image.... Because its using same Zoom & rotation values of old image....

Requirement :

But once we upload new image, it should reset value of Zoom & Rotation to null....

Code snippet :

var target;
const imageUrl = "https://i.imgur.com/RzEm1WK.png";

let jsonData = {
    "layers": [{
        "x": 0,
        "height": 612,
        "layers": [{
            "x": 160,
            "src": "ax0HVTs.png",
            "y": 291,
            "height": 296,
            "width": 429,
            "name": "mask_1"
        }, {
            "x": 25,
            "src": "hEM2kEP.png",
            "height": 324,
            "width": 471,
            "y": 22,
            "name": "mask_2"
        }],
        "y": 0,
        "width": 612
    }]
};

const containerElement = $('#container');
const fileUp = $('#fileup');
let mask;

$(function() {

    // Upload image onclick mask image

    containerElement.click(function(e) {
        var res = e.target;
        target = res.id;
        if (e.target.getContext) {
            // click only inside Non Transparent part
            var pixel = e.target.getContext('2d').getImageData(e.offsetX, e.offsetY, 1, 1).data;
            if (pixel[3] === 255) {
                setTimeout(() => {
                    $('#fileup').click();
                }, 20);
            }
        }
    });

    // Fetch mask images from json file - IGNORE this code

    function getAllSrc(layers) {
        let arr = [];
        layers.forEach(layer => {
            if (layer.src) {
                arr.push({
                    src: layer.src,
                    x: layer.x,
                    y: layer.y,
                    height: layer.height,
                    width: layer.width,
                    name: layer.name
                });
            } else if (layer.layers) {
                let newArr = getAllSrc(layer.layers);
                if (newArr.length > 0) {
                    newArr.forEach(({
                        src,
                        x,
                        y,
                        height,
                        width,
                        name
                    }) => {
                        arr.push({
                            src,
                            x: (layer.x + x),
                            y: (layer.y + y),
                            height,
                            width,
                            name: (name)
                        });
                    });
                }
            }
        });
        return arr;
    }

    function json(data) {
        var width = 0;
        var height = 0;

        let arr = getAllSrc(data.layers);
        let layer1 = data.layers;
        width = layer1[0].width;
        height = layer1[0].height;
        let counter = 0;
        let table = [];

        // container dimensions
        containerElement.css('width', width + "px").css('height', height + "px").addClass('temp');
        //end

        for (let {
                src,
                x,
                y,
                name
            } of arr) {

            //Get Height and width of mask image [ edit button ]
            var ImagePosition = arr;
            //code end

            var mask = $(".container").mask({
                imageUrl: imageUrl,

                // Fetch Mask images
                maskImageUrl: 'http://i.imgur.com/' + src,
                // end

                onMaskImageCreate: function(img) {
                    // Mask image positions
                    img.css({
                        "position": "absolute",
                        "left": x + "px",
                        "top": y + "px"
                    });
                    // end

                },
                id: counter
            });
            // here
            table.push(mask);
            fileup.onchange = function() {

                let mask2 = table[target];
                const newImageLoadedId = mask2.loadImage(URL.createObjectURL(fileup.files[0]));
                document.getElementById('fileup').value = "";

                // Edit image

                if ($(".masked-img" + newImageLoadedId).length === 1) {
                    const span = $("<span class=\"pip pip" + newImageLoadedId + "\">" +
                        "<a onclick='document.getElementById(\"dark" + newImageLoadedId +
                        "\").style.display=\"block\";'><span class=\"edit edit" +
                        newImageLoadedId + "\" >Edit </span></a>" +
                        "</span>").insertAfter(".masked-img" + newImageLoadedId).css({
                        "left": ImagePosition[newImageLoadedId].x + (ImagePosition[
                            newImageLoadedId].width / 2) + "px",
                        "top": ImagePosition[newImageLoadedId].y + (ImagePosition[
                            newImageLoadedId].height / 2) + "px"
                    });
                    span.attr('data-id', newImageLoadedId)
                    $("<div id=\'dark" + newImageLoadedId + "\' class=\'dark_content\'>" +
                            $('#demoTemplate').html() +
                            "<a href=\"javascript:void(0)\" onclick=\"document.getElementById(\'dark" +
                            newImageLoadedId + "\').style.display=\'none\'\">Close</a>" + "</div>")
                        .appendTo(".pip" + newImageLoadedId).css({
                            "left": $('.edit' + newImageLoadedId).width() + 2 + "px",
                            "top": "0px"
                        });
                }
                // end   

				//  Remove image

                $("<br/><span id=\"" + newImageLoadedId + "\" class=\"remove\">Remove</span>").insertAfter(".masked-img" + newImageLoadedId).css({
                    "left": ImagePosition[newImageLoadedId].x + (ImagePosition[newImageLoadedId].width / 2) + "px",
                    "top": ImagePosition[newImageLoadedId].y + (ImagePosition[newImageLoadedId].height / 2 + 25) + "px"
                });

                $(".remove").click(function(event) {
                    const canvasId = "canvas#" + event.currentTarget.id;
                    // Delete the uploaded image & icon
                    const ctx = $("canvas")[event.currentTarget.id].getContext("2d");
                    ctx.fillStyle = "white"
                    ctx.fillRect(0, 0, 500, 500)
                    // Delete the Edit button
                    $(this).next().find('.edit').remove()
                    // Delete the Remove button
                    $(this).remove();
                });

                // Remove image code end here....
            };
            counter++;
        }
        return mask;
    }
    mask = json(jsonData);
}); // end of function

// Image code

(function($) {
    window.JQmasks = [];
    $.fn.mask = function(options) {
        // This is the easiest way to have default options.
        var settings = $.extend({
            // These are the defaults.
            maskImageUrl: undefined,
            imageUrl: undefined,
            scale: 1,
            id: new Date().getUTCMilliseconds().toString(),
            x: 0, // image start position
            y: 0, // image start position
            onMaskImageCreate: function(div) {},
            rotate: 0,
        }, options);

        // Create the image properties
        settings.maskImage = new Image
        settings.image = new Image

        // set the cross-origin attributes
        settings.maskImage.setAttribute('crossOrigin', 'anonymous');
        settings.image.setAttribute('crossOrigin', 'anonymous');

        settings.maskImage.onload = function() {
            // once the mask is loaded, load the image
            container.loadImage(settings.imageUrl)
        }

        settings.image.onload = function() {
            // once the image is loaded, render to canvas
            container.drawMask()
            container.drawImage()
        }

        var container = $(this);

        let prevX = 0,
            prevY = 0,
            draggable = false,
            img,
            canvas,
            context,
            image,
            timeout,
            initImage = false,
            startX = settings.x,
            startY = settings.y,
            scale = settings.scale,
            div;

        container.mousePosition = function(event) {
            return {
                x: event.pageX || event.offsetX,
                y: event.pageY || event.offsetY
            };
        }

        container.selected = function(ev) {
            var pos = container.mousePosition(ev);
            var item = $(".masked-img canvas").filter(function() {
                var offset = $(this).offset()
                var x = pos.x - offset.left;
                var y = pos.y - offset.top;
                var d = this.getContext('2d').getImageData(x, y, 1, 1).data;
                return d[0] > 0
            });

            JQmasks.forEach(function(el) {
                var id = item.length > 0 ? $(item).attr("id") : "";
                if (el.id == id)
                    el.item.enable();
                else el.item.disable();
            });
        };

        container.enable = function() {
            draggable = true;
            $(canvas).attr("active", "true");
            div.css({
                "z-index": 2
            });
        }

        container.disable = function() {
            draggable = false;
            $(canvas).attr("active", "false");
            div.css({
                "z-index": 1
            });
        }

        container.getImagePosition = function() {
            return {
                x: settings.x,
                y: settings.y,
                scale: settings.scale
            };
        };

        container.zoom = function(delta) {
            settings.scale += delta;
            settings.scale = Math.max(0.5, Math.max(0, settings.scale));
            console.log('Zoom', settings.scale);					
            context.clearRect(0, 0, canvas.width, canvas.height);
            container.drawMask()
            container.drawImage();
        }

        container.rotate = function(rotation) {
            settings.rotate += rotation * Math.PI / 180;
             console.log('Rotation', settings.rotate);
            context.clearRect(0, 0, canvas.width, canvas.height);
            container.drawMask()
            container.drawImage();
        }

        container.drawMask = function() {
            canvas.width = settings.maskImage.width;
            canvas.height = settings.maskImage.height;
            context.save();
            context.beginPath();
            context.globalCompositeOperation = "source-over";
            // draw the masked image after scaling
            context.drawImage(settings.maskImage, 0, 0, settings.maskImage.width, settings.maskImage
                .height);
            context.restore()
        };

        container.drawImage = function() {
            const img = settings.image

            settings.x = settings.x == 0 && initImage ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
            settings.y = settings.y == 0 && initImage ? (canvas.height - (img.height * settings.scale)) / 2 : settings.y;

            context.globalCompositeOperation = 'source-atop';
            context.save();
            context.translate(settings.x + img.width / 2, settings.y + img.height / 2);
            context.rotate(settings.rotate);
            context.scale(settings.scale, settings.scale);
            context.translate(-(settings.x + img.width / 2), -(settings.y + img.height / 2));
            let width = img.width,
                height = img.height;
            context.drawImage(img, settings.x, settings.y, width, height);
          //context.setTransform('settings.scale' , 'settings.rotate',1,0,0,1);
		  //console.log('matrix', 'context.setTransform');
			context.restore();
            initImage = false;           
        }

        // change the draggable image

        container.loadImage = function(imageUrl) {
            console.log("selected image, loading");
            settings.y = startY;
            settings.x = startX;
            prevX = prevY = 0;
            initImage = true;
            settings.image.src = imageUrl; // CHANGED

            //  remove button
            return settings.id;
        };

        container.onDragStart = function(evt) {
           // console.log('Draw started');
            if (evt.target.getContext) {
                var pixel = evt.target.getContext('2d').getImageData(evt.offsetX, evt.offsetY, 1, 1).data;

                $(canvas).attr("active", "true");
                container.selected(evt);
                prevX = evt.clientX;
                prevY = evt.clientY;
                var img = new Image();
                evt.originalEvent.dataTransfer.setDragImage(img, 10, 10);
                evt.originalEvent.dataTransfer.setData('text/plain', 'anything');

            }
        };

        container.onDragOver = function(evt) {
          //  console.log('Drag over');
            if (evt.target.getContext) {
                var pixel = evt.target.getContext('2d').getImageData(evt.offsetX, evt.offsetY, 1, 1).data;
                if (pixel[3] === 255) {
                    if (draggable && $(canvas).attr("active") === "true") {
                        var x = settings.x + evt.clientX - prevX;
                        var y = settings.y + evt.clientY - prevY;
                        if (x == settings.x && y == settings.y)
                            return; // position has not changed
                        settings.x += evt.clientX - prevX;
                        settings.y += evt.clientY - prevY;
                        prevX = evt.clientX;
                        prevY = evt.clientY;
                        clearTimeout(timeout);
                        timeout = setTimeout(function() {
                            container.drawMask();
                            container.drawImage();
                        }, 1);
                    }
                } else {
                    evt.stopPropagation();
                    return false;
                }
            }
        };

        container.loadMaskImage = function(imageUrl, from) {
            console.log('loading mask image from', imageUrl, from)
            canvas = document.createElement("canvas");
            context = canvas.getContext('2d');
            canvas.setAttribute("draggable", "true");
            canvas.setAttribute("id", settings.id);
            // settings.maskImageUrl = imageUrl;
            settings.maskImage.src = imageUrl // CHANGED

            div = $("<div/>", {
                "class": "masked-img"
            }).append(canvas);

            // div.find("canvas").on('touchstart mousedown', function(event)
            div.find("canvas").on('dragstart', function(event) {
                if (event.handled === false) return;
                event.handled = true;
                container.onDragStart(event);
            });

            div.find("canvas").on('touchend mouseup', function(event) {
                if (event.handled === false) return;
                event.handled = true;
                container.selected(event);
            });

            div.find("canvas").bind("dragover", container.onDragOver);

            container.append(div);
            if (settings.onMaskImageCreate)
                settings.onMaskImageCreate(div);

            // container.loadImage(settings.imageUrl);
            // Moved this to the settings.maskImage.onload
        };
        container.loadMaskImage(settings.maskImageUrl);
        JQmasks.push({
            item: container,
            id: settings.id
        })
        // Edit image
        div.addClass('masked-img' + settings.id);
        div.attr('data-id', settings.id);
       
        return container;
    };
}(jQuery));

// Zoom

function zoom_in(button) {
    const id = $(button).parents('.pip').attr('data-id')
    JQmasks[id].item.zoom(0.1);
}

function zoom_out(button) {
    const id = $(button).parents('.pip').attr('data-id')
    JQmasks[id].item.zoom(-0.1);
}

// Rotate

function rotate_right(button) {
    const id = $(button).parents('.pip').attr('data-id')
    JQmasks[id].item.rotate(20);
}

function rotate_left(button) {
    const id = $(button).parents('.pip').attr('data-id')
    JQmasks[id].item.rotate(-20);
}
.container {
        background: silver;
        position: relative;
    }

    .container img {
        position: absolute;
        top: 0;
        bottom: 250px;
        left: 0;
        right: 0;
        margin: auto;
        z-index: 999;
    }

    .masked-img {
        overflow: hidden;
        position: relative;
    }

    .pip {
        display: inline-block;
        margin: 0;
        position: absolute;
    }

    .edit {
        display: block;
        background: #444;
        border: 1px solid black;
        color: white;
        text-align: center;
        cursor: pointer;
        position: absolute;
        z-index: 3;
    }

    .edit:hover {
        background: white;
        color: black;
        position: absolute;
        z-index: 3;
    }   

    .dark_content {
        display: none;
        position: relative;
        top: 25%;
        left: 25%;
        width: 250px;
        height: 250px;
        padding: 16px;
        border: 16px solid orange;
        background-color: white;
        z-index: 1002;
        overflow: auto;
    }	

.remove {
	background: #444;
	border: 1px solid black;
	color: white;
	text-align: center;
	cursor: pointer;
	position: absolute;
	z-index: 3;
   }

    .remove:hover {
	background: white;
	color: black;
   }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
    </script>

    <input id="fileup" name="fileup" type="file" style="display:none">

    <div id="container" class="container">
    </div>

    <template id='demoTemplate'>
        <span>
            <div class="btn-group">
                <button type="button" class="js-zoom-in" onclick="zoom_in(this)">Zoom In</button>
                <button type="button" class="js-zoom-out" onclick="zoom_out(this)">Zoom Out</button>
                <button type="button" class="js-rotate-right" onclick="rotate_right(this)">Rotate Right</button>
                <button type="button" class="js-rotate-left" onclick="rotate_left(this)">Rotate Left</button>
            </div>
            <img id="image" src="" style="display:none">
        </span>
    </template>

Here is Jsfiddle & Codepen


Solution

  • In load image function reset the scale and rotate property of settings variable. This should solve the issue. Check the code below.

    var target;
    const imageUrl = "https://i.imgur.com/RzEm1WK.png";
    
    let jsonData = {
        "layers": [{
            "x": 0,
            "height": 612,
            "layers": [{
                "x": 160,
                "src": "ax0HVTs.png",
                "y": 291,
                "height": 296,
                "width": 429,
                "name": "mask_1"
            }, {
                "x": 25,
                "src": "hEM2kEP.png",
                "height": 324,
                "width": 471,
                "y": 22,
                "name": "mask_2"
            }],
            "y": 0,
            "width": 612
        }]
    };
    
    const containerElement = $('#container');
    const fileUp = $('#fileup');
    let mask;
    
    $(function() {
    
        // Upload image onclick mask image
    
        containerElement.click(function(e) {
            var res = e.target;
            target = res.id;
            if (e.target.getContext) {
                // click only inside Non Transparent part
                var pixel = e.target.getContext('2d').getImageData(e.offsetX, e.offsetY, 1, 1).data;
                if (pixel[3] === 255) {
                    setTimeout(() => {
                        $('#fileup').click();
                    }, 20);
                }
            }
        });
    
        // Fetch mask images from json file - IGNORE this code
    
        function getAllSrc(layers) {
            let arr = [];
            layers.forEach(layer => {
                if (layer.src) {
                    arr.push({
                        src: layer.src,
                        x: layer.x,
                        y: layer.y,
                        height: layer.height,
                        width: layer.width,
                        name: layer.name
                    });
                } else if (layer.layers) {
                    let newArr = getAllSrc(layer.layers);
                    if (newArr.length > 0) {
                        newArr.forEach(({
                            src,
                            x,
                            y,
                            height,
                            width,
                            name
                        }) => {
                            arr.push({
                                src,
                                x: (layer.x + x),
                                y: (layer.y + y),
                                height,
                                width,
                                name: (name)
                            });
                        });
                    }
                }
            });
            return arr;
        }
    
        function json(data) {
            var width = 0;
            var height = 0;
    
            let arr = getAllSrc(data.layers);
            let layer1 = data.layers;
            width = layer1[0].width;
            height = layer1[0].height;
            let counter = 0;
            let table = [];
    
            // container dimensions
            containerElement.css('width', width + "px").css('height', height + "px").addClass('temp');
            //end
    
            for (let {
                    src,
                    x,
                    y,
                    name
                } of arr) {
    
                //Get Height and width of mask image [ edit button ]
                var ImagePosition = arr;
                //code end
    
                var mask = $(".container").mask({
                    imageUrl: imageUrl,
    
                    // Fetch Mask images
                    maskImageUrl: 'http://i.imgur.com/' + src,
                    // end
    
                    onMaskImageCreate: function(img) {
                        // Mask image positions
                        img.css({
                            "position": "absolute",
                            "left": x + "px",
                            "top": y + "px"
                        });
                        // end
    
                    },
                    id: counter
                });
                // here
                table.push(mask);
                fileup.onchange = function() {
    
                    let mask2 = table[target];
                    const newImageLoadedId = mask2.loadImage(URL.createObjectURL(fileup.files[0]));
                    document.getElementById('fileup').value = "";
    
                    // Edit image
    
                    if ($(".masked-img" + newImageLoadedId).length === 1) {
                        const span = $("<span class=\"pip pip" + newImageLoadedId + "\">" +
                            "<a onclick='document.getElementById(\"dark" + newImageLoadedId +
                            "\").style.display=\"block\";'><span class=\"edit edit" +
                            newImageLoadedId + "\" >Edit </span></a>" +
                            "</span>").insertAfter(".masked-img" + newImageLoadedId).css({
                            "left": ImagePosition[newImageLoadedId].x + (ImagePosition[
                                newImageLoadedId].width / 2) + "px",
                            "top": ImagePosition[newImageLoadedId].y + (ImagePosition[
                                newImageLoadedId].height / 2) + "px"
                        });
                        span.attr('data-id', newImageLoadedId)
                        $("<div id=\'dark" + newImageLoadedId + "\' class=\'dark_content\'>" +
                                $('#demoTemplate').html() +
                                "<a href=\"javascript:void(0)\" onclick=\"document.getElementById(\'dark" +
                                newImageLoadedId + "\').style.display=\'none\'\">Close</a>" + "</div>")
                            .appendTo(".pip" + newImageLoadedId).css({
                                "left": $('.edit' + newImageLoadedId).width() + 2 + "px",
                                "top": "0px"
                            });
                    }
                    // end   
    
    				//  Remove image
    
                    $("<br/><span id=\"" + newImageLoadedId + "\" class=\"remove\">Remove</span>").insertAfter(".masked-img" + newImageLoadedId).css({
                        "left": ImagePosition[newImageLoadedId].x + (ImagePosition[newImageLoadedId].width / 2) + "px",
                        "top": ImagePosition[newImageLoadedId].y + (ImagePosition[newImageLoadedId].height / 2 + 25) + "px"
                    });
    
                    $(".remove").click(function(event) {
                        const canvasId = "canvas#" + event.currentTarget.id;
                        // Delete the uploaded image & icon
                        const ctx = $("canvas")[event.currentTarget.id].getContext("2d");
                        ctx.fillStyle = "white"
                        ctx.fillRect(0, 0, 500, 500)
                        // Delete the Edit button
                        $(this).next().find('.edit').remove()
                        // Delete the Remove button
                        $(this).remove();
                    });
    
                    // Remove image code end here....
                };
                counter++;
            }
            return mask;
        }
        mask = json(jsonData);
    }); // end of function
    
    // Image code
    
    (function($) {
        window.JQmasks = [];
        $.fn.mask = function(options) {
            // This is the easiest way to have default options.
            var settings = $.extend({
                // These are the defaults.
                maskImageUrl: undefined,
                imageUrl: undefined,
                scale: 1,
                id: new Date().getUTCMilliseconds().toString(),
                x: 0, // image start position
                y: 0, // image start position
                onMaskImageCreate: function(div) {},
                rotate: 0,
            }, options);
    
            // Create the image properties
            settings.maskImage = new Image
            settings.image = new Image
    
            // set the cross-origin attributes
            settings.maskImage.setAttribute('crossOrigin', 'anonymous');
            settings.image.setAttribute('crossOrigin', 'anonymous');
    
            settings.maskImage.onload = function() {
                // once the mask is loaded, load the image
                container.loadImage(settings.imageUrl)
            }
    
            settings.image.onload = function() {
                // once the image is loaded, render to canvas
                container.drawMask()
                container.drawImage()
            }
    
            var container = $(this);
    
            let prevX = 0,
                prevY = 0,
                draggable = false,
                img,
                canvas,
                context,
                image,
                timeout,
                initImage = false,
                startX = settings.x,
                startY = settings.y,
                scale = settings.scale,
                div;
    
            container.mousePosition = function(event) {
                return {
                    x: event.pageX || event.offsetX,
                    y: event.pageY || event.offsetY
                };
            }
    
            container.selected = function(ev) {
                var pos = container.mousePosition(ev);
                var item = $(".masked-img canvas").filter(function() {
                    var offset = $(this).offset()
                    var x = pos.x - offset.left;
                    var y = pos.y - offset.top;
                    var d = this.getContext('2d').getImageData(x, y, 1, 1).data;
                    return d[0] > 0
                });
    
                JQmasks.forEach(function(el) {
                    var id = item.length > 0 ? $(item).attr("id") : "";
                    if (el.id == id)
                        el.item.enable();
                    else el.item.disable();
                });
            };
    
            container.enable = function() {
                draggable = true;
                $(canvas).attr("active", "true");
                div.css({
                    "z-index": 2
                });
            }
    
            container.disable = function() {
                draggable = false;
                $(canvas).attr("active", "false");
                div.css({
                    "z-index": 1
                });
            }
    
            container.getImagePosition = function() {
                return {
                    x: settings.x,
                    y: settings.y,
                    scale: settings.scale
                };
            };
    
            container.zoom = function(delta) {
                settings.scale += delta;
                settings.scale = Math.max(0.5, Math.max(0, settings.scale));
                console.log('Zoom', settings.scale);					
                context.clearRect(0, 0, canvas.width, canvas.height);
                container.drawMask()
                container.drawImage();
            }
    
            container.rotate = function(rotation) {
                settings.rotate += rotation * Math.PI / 180;
                 console.log('Rotation', settings.rotate);
                context.clearRect(0, 0, canvas.width, canvas.height);
                container.drawMask()
                container.drawImage();
            }
    
            container.drawMask = function() {
                canvas.width = settings.maskImage.width;
                canvas.height = settings.maskImage.height;
                context.save();
                context.beginPath();
                context.globalCompositeOperation = "source-over";
                // draw the masked image after scaling
                context.drawImage(settings.maskImage, 0, 0, settings.maskImage.width, settings.maskImage
                    .height);
                context.restore()
            };
    
            container.drawImage = function() {
                const img = settings.image
    
                settings.x = settings.x == 0 && initImage ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
                settings.y = settings.y == 0 && initImage ? (canvas.height - (img.height * settings.scale)) / 2 : settings.y;
    
                context.globalCompositeOperation = 'source-atop';
                context.save();
                context.translate(settings.x + img.width / 2, settings.y + img.height / 2);
                context.rotate(settings.rotate);
                context.scale(settings.scale, settings.scale);
                context.translate(-(settings.x + img.width / 2), -(settings.y + img.height / 2));
                let width = img.width,
                    height = img.height;
                context.drawImage(img, settings.x, settings.y, width, height);
              //context.setTransform('settings.scale' , 'settings.rotate',1,0,0,1);
    		  //console.log('matrix', 'context.setTransform');
    			context.restore();
                initImage = false;           
            }
    
            // change the draggable image
    
            container.loadImage = function(imageUrl) {
                console.log("selected image, loading");
                settings.y = startY;
                settings.x = startX;
                settings.scale = 1;
                settings.rotate = 0;
                prevX = prevY = 0;
                initImage = true;
                settings.image.src = imageUrl; // CHANGED
    
                //  remove button
                return settings.id;
            };
    
            container.onDragStart = function(evt) {
               // console.log('Draw started');
                if (evt.target.getContext) {
                    var pixel = evt.target.getContext('2d').getImageData(evt.offsetX, evt.offsetY, 1, 1).data;
    
                    $(canvas).attr("active", "true");
                    container.selected(evt);
                    prevX = evt.clientX;
                    prevY = evt.clientY;
                    var img = new Image();
                    evt.originalEvent.dataTransfer.setDragImage(img, 10, 10);
                    evt.originalEvent.dataTransfer.setData('text/plain', 'anything');
    
                }
            };
    
            container.onDragOver = function(evt) {
              //  console.log('Drag over');
                if (evt.target.getContext) {
                    var pixel = evt.target.getContext('2d').getImageData(evt.offsetX, evt.offsetY, 1, 1).data;
                    if (pixel[3] === 255) {
                        if (draggable && $(canvas).attr("active") === "true") {
                            var x = settings.x + evt.clientX - prevX;
                            var y = settings.y + evt.clientY - prevY;
                            if (x == settings.x && y == settings.y)
                                return; // position has not changed
                            settings.x += evt.clientX - prevX;
                            settings.y += evt.clientY - prevY;
                            prevX = evt.clientX;
                            prevY = evt.clientY;
                            clearTimeout(timeout);
                            timeout = setTimeout(function() {
                                container.drawMask();
                                container.drawImage();
                            }, 1);
                        }
                    } else {
                        evt.stopPropagation();
                        return false;
                    }
                }
            };
    
            container.loadMaskImage = function(imageUrl, from) {
                console.log('loading mask image from', imageUrl, from)
                canvas = document.createElement("canvas");
                context = canvas.getContext('2d');
                canvas.setAttribute("draggable", "true");
                canvas.setAttribute("id", settings.id);
                // settings.maskImageUrl = imageUrl;
                settings.maskImage.src = imageUrl // CHANGED
    
                div = $("<div/>", {
                    "class": "masked-img"
                }).append(canvas);
    
                // div.find("canvas").on('touchstart mousedown', function(event)
                div.find("canvas").on('dragstart', function(event) {
                    if (event.handled === false) return;
                    event.handled = true;
                    container.onDragStart(event);
                });
    
                div.find("canvas").on('touchend mouseup', function(event) {
                    if (event.handled === false) return;
                    event.handled = true;
                    container.selected(event);
                });
    
                div.find("canvas").bind("dragover", container.onDragOver);
    
                container.append(div);
                if (settings.onMaskImageCreate)
                    settings.onMaskImageCreate(div);
    
                // container.loadImage(settings.imageUrl);
                // Moved this to the settings.maskImage.onload
            };
            container.loadMaskImage(settings.maskImageUrl);
            JQmasks.push({
                item: container,
                id: settings.id
            })
            // Edit image
            div.addClass('masked-img' + settings.id);
            div.attr('data-id', settings.id);
           
            return container;
        };
    }(jQuery));
    
    // Zoom
    
    function zoom_in(button) {
        const id = $(button).parents('.pip').attr('data-id')
        JQmasks[id].item.zoom(0.1);
    }
    
    function zoom_out(button) {
        const id = $(button).parents('.pip').attr('data-id')
        JQmasks[id].item.zoom(-0.1);
    }
    
    // Rotate
    
    function rotate_right(button) {
        const id = $(button).parents('.pip').attr('data-id')
        JQmasks[id].item.rotate(20);
    }
    
    function rotate_left(button) {
        const id = $(button).parents('.pip').attr('data-id')
        JQmasks[id].item.rotate(-20);
    }
    .container {
            background: silver;
            position: relative;
        }
    
        .container img {
            position: absolute;
            top: 0;
            bottom: 250px;
            left: 0;
            right: 0;
            margin: auto;
            z-index: 999;
        }
    
        .masked-img {
            overflow: hidden;
            position: relative;
        }
    
        .pip {
            display: inline-block;
            margin: 0;
            position: absolute;
        }
    
        .edit {
            display: block;
            background: #444;
            border: 1px solid black;
            color: white;
            text-align: center;
            cursor: pointer;
            position: absolute;
            z-index: 3;
        }
    
        .edit:hover {
            background: white;
            color: black;
            position: absolute;
            z-index: 3;
        }   
    
        .dark_content {
            display: none;
            position: relative;
            top: 25%;
            left: 25%;
            width: 250px;
            height: 250px;
            padding: 16px;
            border: 16px solid orange;
            background-color: white;
            z-index: 1002;
            overflow: auto;
        }	
    
    .remove {
    	background: #444;
    	border: 1px solid black;
    	color: white;
    	text-align: center;
    	cursor: pointer;
    	position: absolute;
    	z-index: 3;
       }
    
        .remove:hover {
    	background: white;
    	color: black;
       }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
        </script>
    
        <input id="fileup" name="fileup" type="file" style="display:none">
    
        <div id="container" class="container">
        </div>
    
        <template id='demoTemplate'>
            <span>
                <div class="btn-group">
                    <button type="button" class="js-zoom-in" onclick="zoom_in(this)">Zoom In</button>
                    <button type="button" class="js-zoom-out" onclick="zoom_out(this)">Zoom Out</button>
                    <button type="button" class="js-rotate-right" onclick="rotate_right(this)">Rotate Right</button>
                    <button type="button" class="js-rotate-left" onclick="rotate_left(this)">Rotate Left</button>
                </div>
                <img id="image" src="" style="display:none">
            </span>
        </template>

    Hope this helps :)