We are displaying Two mask images in page.
Once User click on Mask images, we are displaying File upload dialog box, so that user will upload their own image and click on save button.
Once user click on "save" button, we are saving those images in server....
Issue :
Only latest uploaded image is saving in server....
Example : User upload car to Mask1 - > User upload bike to Mask2 - > Click save - > Only Bike image save in server....
Requirement :
We need to save both the uploaded images in server. Means Both Bike & Car image need to be saved....
Here is Codepen , Fiddle & Pastebin
var target;
const imageUrl = "";
var jsonData = {
"layers": [{
"x": 0,
"height": 600,
"layers": [{
"x": 160,
"src": "ax0HVTs.png",
"y": 281,
"height": 296,
"width": 429,
"name": "mask_1"
}, {
"x": 25,
"src": "hEM2kEP.png",
"height": 324,
"width": 471,
"y": 9,
"name": "mask_2"
}],
"y": 0,
"width": 612
}]
};
const containerElement = $('#container');
const fileUp = $('#fileup');
let mask;
let file;
$(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
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;
console.log(layer1);
let counter = 0;
let table = [];
containerElement.css('width', width + "px").css('height', height + "px").addClass('temp');
for (let {
src,
x,
y,
name
} of arr) {
var ImagePosition = arr;
var imageUrl1 = imageUrl;
var mask = $(".container").mask({
imageUrl: name.indexOf('mask_') !== -1 ? imageUrl1 : undefined,
// Mask images
maskImageUrl: 'https://i.imgur.com/' + src,
// end
onMaskImageCreate: function(img) {
// Mask image positions
img.css({
"position": "absolute",
"left": x + "px",
"top": y + "px"
});
// end
},
id: counter
});
ImagePosition.map(function(cur, index) {
var available = cur.name.includes('mask_');
if (!available) {
$('.masked-img' + index).css('pointer-events', 'none');
}
});
table.push(mask);
fileup.onchange = function() {
file = fileup.files[0];
let mask2 = table[target];
const newImageLoadedId = mask2.loadImage(URL.createObjectURL(fileup.files[0]));
//document.getElementById('fileup').value = "";
};
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.
const 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, true)
container.drawMask()
}
settings.image.onload = function() {
// once the image is loaded, render to canvas
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.drawMask = function() {
if (!settings.maskImage) return true;
canvas.width = settings.maskImage.width;
canvas.height = settings.maskImage.height;
context.save();
context.beginPath();
context.globalCompositeOperation = "source-over";
// draw the masked image after scaling
if (settings.maskImage)
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;
if (img)
context.drawImage(img, settings.x, settings.y, width, height);
context.restore();
initImage = false;
}
container.loadImage = function(imageUrl, isMask) {
if (!imageUrl) return true;
settings.y = startY;
settings.x = startX;
settings.scale = 1;
settings.rotate = 0;
prevX = prevY = 0;
initImage = true;
settings.image.src = imageUrl; // CHANGED
if (!isMask)
container.data('image_set' + settings.id, true)
return settings.id;
};
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);
container.append(div);
if (settings.onMaskImageCreate)
settings.onMaskImageCreate(div);
};
if (settings.maskImageUrl) {
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);
// ends
return container;
};
}(jQuery));
//Download image to server
function test() {
var canvas = document.getElementById("1");
var dataURL = canvas.toDataURL(); // THE BASE 64 DATA
var dataFileName = document.getElementById('fileup').value.replace(/.*(\/|\\)/, ''); // GET THE FILE NAME THAT USER CHOSE
var dataFileType = dataFileName.split('.').pop();
data = new FormData();
data.append('imgBase64', file, file.name);
$.ajax({
type: "POST",
url: "save.php",
cache:false,
contentType: false,
processData: false,
data: data
}).done(function(o) {
var response = JSON.parse(o);
$('body').prepend('<img src="test/multiple/' + response.data[0].fileName + '" style="height: 200px; width: auto;">');
});
}
.save {
font-size:20px;
}
.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;
}
<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:block; position:relative; top : 1000px; ">
<div id="container" class="container">
</div>
<button class ="save" onclick="test()">Save image to server</button>
Save.php
<?php
if (isset($_FILES['imgBase64'])) {
$fname = $_FILES["imgBase64"]["name"]; // THE FILENAME THE USER CHOSE IS RECEIVED VIA POST
$img = filter_input(INPUT_POST, 'imgBase64'); // THE BASE64 ENCODING RECEIVED VIA POST
$imgtype = $_FILES["imgBase64"]["type"]; // THE FILE TYPE / EXTENSION IS RECEIVED VIA POST
if(move_uploaded_file($_FILES["imgBase64"]["tmp_name"], "test/multiple/".$fname)){
echo '{"error":false, "message":null,"data":[{"msg": "Image has been saved successfully!", "fileName": "' . $fname . '"}]}';
}
else{
echo '{"error":true, "message":"File not uploaded"}';
}
}
?>