We cant able to drag the uploaded image in right part of 1st mask image.... Because it is overlapped with the left part of second image....
Here is
I have recreated the plugin, now it only uses canvas to mask, t here is no css mask
involved any more.
$(document).ready(function() {
var maskedImageUrla = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQMAAAEWCAMAAABVFALRAAAAaVBMVEVHcEz////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////dvhWBAAAAInRSTlMABWcZ/QmP9IX67TovokSZ5d0hD65eudRVbnvATScSx89zp18fZAAABsRJREFUGBnlwAeCo0gWBNAAEhLvjbyJ+x9yd6a7p8vIAEIq5c+Hd+FGkQOreT3JPWyWxCS5g8U2/NcZ1jr0/CWDreqSvw2wVBrzj8iBlXLNv1LYaKX4wRoW6viRymAfl59VsI7Lrw6wTMdvVrBLoviVKmCVOuZ3A2ziD7zEg0VaXtTBHhtelsEaOa8oYYta85o97OCceNUadgh53RZWSHiDOsACfsVbXFgg4E095Et4W9RAOr/iHR2kC3lPC+G8iPdoH7IFvG8F0byI97UQLeAI0QGCeRHHcCFYyFGOkOsQcZw9xAo5UgipGs2RSgdChRxtBZl8zdF6yLTheKqGRI7mBCEk2nGK2IdAGSdxIY8fcZIT5FlxohzitJyohTROxIlUDWF2nKyAMAUn0x5kiTldCFESzhA3kCTkHGdIMnCO0occHudxIceK85Q+xCg40xpiDJyp9CGErzjXGkIknK30IYPL+c6QIeB8cQMRtnxACBFiPkB7EKDhQwoIkPAh0R7m6/iYFuYL+KAcxuv5oBOMV/FRLkwX80EqbmC4iA8LYDaHD1NRDaN5XEALo+25hB1MlnAJlQ+D5VxECIOtuIhoD3N1XITawlxrLqSDsdZcSNnAVBsupYCpXC4mh6F2XEzlw0wplxPATAcuR6UwU8TlDA6MVHFBGxhpywVFKUyUcUmDAwOFXFSIt+OlO3cTFhmQFUEQhud11+UePnC5KJXgXRzyc9GfYsVf1P+RSvEXvS3WuYd/5VxW5eMNpOu25Ah6G7hJk3JhBX7Yft1qUnG8mEvL8XOaVVbyDZQH/Ax/feS7aPET9oHmG3HxcnnP96L3eCnfrfh2Tg5exws131GAV/EyxTe1w2usNd9W7OEF9ke+s6ODZ3PCiK+mOIEK8GTpwNfTnGSHZ3I2iu9P13ie+kgjnHw8S6dpiAJPsqE5OjxFSIPoFE8Q0ihVg8WFNEyPpZ1pnBDL6migFZaUKxpIp1jOXtNI1QFLaSoaqsdSehorwDLWNFiHJaQRDRbleJxf0WhxjYcFNFzV4EEpjbd18JgjjacKPKSjBGc8wCkpgdphPpcy6ARzOSVlULGHmTqKMTSY50Qx1NbBHCklyTBHQFECzBBTlg0mSyiM6jBVSGmiHBOdKI5OMIlHgXSKKVwKpMoaE7QUqfIwXkWZhgZjOZTq6GOkPcXqHYyTU64W47iUS2UYJaRkBcYoKFqAEXrKFuC+E4ULcVdM6Ta4R1G8M+6gBda4jTZwcVNEG7i4paQV1rhhSzuccV2maIczrgpoiw2uWdMaG1yxoz1CXJbSGoohLvJpkxAXlbRJgUtaWiVz8N2GdmkdfJPQMr2PrxxNyxwbfNXSNicPX6xonaHGZ46mdcoanxW0T5nik5QW0jk+GWgfFa3w0Zk2Ui4+OES0UogPMtqpwF8JLdX6+M+Wlto2+COhrQYPfxS0VdngtyamnRRr/NHRUjH+2tJOLf7aR7TSGR+EtFKCD/xK0T7Kx0c5LXTCZyHtE+CLjNZZ4Qunp21qfOWfaJcY3x0qWqXFBV5Jm5xxyT5WtEeCyyLaw8dlOa0x4BqXtghwlUtL7HBdRzsccMNO0wIn3JSWlC/AbYee4uW4wwkpnPJx105TtCNGqAcKpkKM0bQULME454hSRQ5GSgcK1WM0J4wo0hkT7LeUKMUkq5LiaEzkbzSFyTCZVyiK0mGGtKeiHAfMkg+UQp0wk9MNFGKD+ZJWUYIUj/DCmMaL8SCnO9JsqsDj0kLTZDsswXePNFbkYyF1ONBMLRZUr7eK5umwrGaVaRrmgMU5eXCiQbZ4jmYXDDTEGs9z2IVbzbenPDyXk7rZoPjOeryCn6yzk+abWuF16vxcHDXfTezg1bx8XfRVxLcR4Kd4SbcptqXiPxR/UI2fVifdpmgHzZ/S4234+7wLs2PMfyi+zg5vx9/v1kE7aL5I6eBtebkb9CWfboN31yRusNV8HuXBDPUq7GM+RQuT7Lui4uJymKbZBQOXVMFIXpdpLuUMYyVBxSVEB5hsH5Z8WAbTJYXmYxKYz+mOfMAAGdIs4lwupDiEmrNoH3I0m5gzFBDF32hOlkKYQ6A4zRHypEdO0kEiV3O82IFI9ZGjbSBVyJG0D7F2mmOoEIKlMUfQDSSrK94XQjav4j3RAcJ5Je8IIF4dK94SebBAxFsK2KDjDaqGFQpel8EOfsWr9rBEwitUC2sEvCKFNZqYF7WwiMuLEljEKXlBD6u4vCCHVXzNb7awTMBvclhmzy/UCdbp+cUO1kn42REWCviB0jVslPEvDUu5mr9ta9iqWW81VVUkGOV/xCNgIHRY9GIAAAAASUVORK5CYII=";
var maskedImageUrlb = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaAAAAGECAMAAABH1QRLAAAAXVBMVEVHcEz///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+EHRzTAAAAHnRSTlMAS6Ph+PEC/BEI6SQaLY0/ethWzsQ0uoSXZ6xws1/MHbQyAAALUElEQVQYGe3AB2KjSBQE0AKaDuQgUK77H3PXE+2xZSVCg/6DuMTmwX4bbuooiRV/UiqO2v4QbvdBbiFmovNmG9aKPxleEG92+9JCTCo771rDOyT9tskgpuDKouZDovCcQYwqPfaKz6i3HcQ4XFBEHEBSlBBD02UYczDRNoUYULqNOLDN2UEMwjU9x6B2KcTTul3M0fSBhniC29ccV3S0EA9y+4TjU0UG8QB9jjgNU1iIewU1p6MqB3GPcsNpxXsNcav8xOnVJcRN0pDzOKUQ12hbGM7FVA7iW65SnFNUQlzmjjHnZbhzEBekLT2QlBBf2iv6odAQn9gTvdGmEB/pMqFHVAPxni5o6JXCQfyRtvTOxkL80sT0UJJjWq47F4fTIQx3RbE97s9BmadWY3auoJ9UgIm47lycEn5JtUWTYUZZS2/tMbosqA4Jr0nCY6cxj5geKzRGpIMw4c3UZhtkmNrRGPrs4DCWrEp4tyg8p5iOC+k5s7EYgw5OfFRUZZiG3dB/rcXg7DHiUzZnh/GlNZegthhWFxo+Te06jCyPuQy1xXB0s+FA6qPFmGIuRW0xEN3UHJAJS4wlUIaL0ToMIq85tHrvMIbAcEl6h+fpynAEqsgwuMBwWU4aT9LZhmMJcwwrMFyaEE9qYo7okGJAgeHyFHiGPXBkO4uhBIZLtMfjyoSji88YRmC4TCUe5AoaTqAtMYDAcKFUiofkNacSZnhWYLhYtcP9dKM4HbN1eEpguGAh7nfktKIAT0gVF22Pe205uUOGR9mIy2Y63KfiDNQZj9E9ly6xuMee8+gzPKLg8h1wh4ZziRvc78w12ONmpeF8Qod7Ga6BSXGrmHOqU9wlSwxXodW4SZYYzkoFuINruRYVbmFrzm6rcbOQq2FyXOc29EBvcaMjV6TVuOpALyQdblIarske12zpCXPEDbKEq6IyfC+gP0KHa/SG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";
// maskedImage one
var mask1 = $(".container").mask({
maskImageUrl: maskedImageUrla,
onMaskImageCreate: function(img) {
// add your style to the img example below
img.css({
"left": 105,
"top": 105
})
}
});
// maskedImage two
var mask2 = $(".container").mask({
maskImageUrl: maskedImageUrlb,
});
fileupa1.onchange = function() {
mask1.loadImage(URL.createObjectURL(fileupa1.files[0]));
};
fileupa2.onchange = function() {
mask2.loadImage(URL.createObjectURL(fileupa2.files[0]));
};
}); // end of document ready
// jq plugin for mask
(function($) {
var 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) {},
}, options);
var container = $(this);
let prevX = 0,
prevY = 0,
draggable = false,
img,
canvas,
context,
image,
timeout,
initImage = false,
startX = settings.x,
startY = settings.y,
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.onDragStart = function(evt) {
container.selected(evt);
prevX = evt.clientX;
prevY = evt.clientY;
};
container.getImagePosition = function() {
return {
x: settings.x,
y: settings.y,
scale: settings.scale
};
};
container.onDragOver = function(evt) {
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;
container.updateStyle();
}
};
container.updateStyle = function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.globalCompositeOperation = "source-over";
image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = settings.maskImageUrl;
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, image.width, image.height);
div.css({
"width": image.width,
"height": image.height
});
};
img = new Image();
img.src = settings.imageUrl;
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function() {
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.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
initImage = false;
};
}, 0);
};
// change the draggable image
container.loadImage = function(imageUrl) {
if (img)
img.remove();
// reset the code.
settings.y = startY;
settings.x = startX;
prevX = prevY = 0;
settings.imageUrl = imageUrl;
initImage = true;
container.updateStyle();
};
// change the masked Image
container.loadMaskImage = function(imageUrl, from) {
if (div)
div.remove();
canvas = document.createElement("canvas");
context = canvas.getContext('2d');
canvas.setAttribute("draggable", "true");
canvas.setAttribute("id", settings.id);
settings.maskImageUrl = imageUrl;
div = $("<div/>", {
"class": "masked-img"
}).append(canvas);
div.find("canvas").on('touchstart mousedown', 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);
};
container.loadMaskImage(settings.maskImageUrl);
JQmasks.push({
item: container,
id: settings.id
});
return container;
};
}(jQuery));
.container {
border: 1px solid #DDDDDD;
display: flex;
background: red;
}
.container canvas {
display: block;
}
.masked-img {
overflow: hidden;
margin-left: 10px;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
image 1
<input id="fileupa1" type="file" >
image 2
<input FILEDIA="1" id="fileupa2" type="file" >
<div class="container">
</div>
CodePen