Here is the basic code for Zoom in & Zoom out: https://codepen.io/kidsdial/pen/ROBpgM,
Now I tried to integrate that code in my Project.
Background:
User clicks on Mask & upload their own image on the mask.
Once image uploaded, Edit Text is displaying on the image.
Once user click on Edit Text, we are displaying pop up box.
Zoom in & Zoom out button displaying.
Issue:
When we click on that button, zoom is not happening for user uploaded image.
Codepen : https://codepen.io/kidsdial/pen/PgxegO
Fiddle : https://jsfiddle.net/kidsdial1/nhswfjr3/
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');
$(function() {
// Upload image onclick mask image
containerElement.click(function(e) {
var res = e.target;
target = res.id;
console.log(target);
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: '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
});
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 - IGNORE this code
if ($(".masked-img" + newImageLoadedId).length === 1) {
$("<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"
});;
$("<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
};
counter++;
}
}
json(jsonData);
}); // end of function
// Image code
(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.getImagePosition = function() {
return {
x: settings.x,
y: settings.y,
scale: settings.scale
};
};
container.updateStyle = function() {
return new Promise((resolve, reject) => {
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
});
resolve();
};
});
};
function renderInnerImage() {
img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = settings.imageUrl;
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;
};
}
// change the draggable image
container.loadImage = function(imageUrl) {
console.log("load");
settings.y = startY;
settings.x = startX;
prevX = prevY = 0;
settings.imageUrl = imageUrl;
initImage = true;
container.updateStyle().then(renderInnerImage);
// sirpepole Add this
return settings.id;
};
container.loadMaskImage = function(imageUrl, from) {
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)
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);
};
container.loadMaskImage(settings.maskImageUrl);
JQmasks.push({
item: container,
id: settings.id
})
// Edit image
div.addClass('masked-img' + settings.id);
// end
return container;
};
}(jQuery));
// Zoom
//document.getElementById("img").src = json(data);
var angle = 0;
var scale = 1;
var $img = $('#image');
$img.on('transform', function() {
$img.css('transform', `rotate(${angle}deg) scale(${scale})`);
});
$('.js-zoom-in').on('click', function() {
scale += 0.25;
if (scale == 2.25) {
scale = 2;
};
$img.trigger('transform');
});
$('.js-zoom-out').on('click', function() {
scale -= 0.25;
if (scale == 0) {
scale = 0.25;
}
$img.trigger('transform');
});
.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;
}
<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">Zoom In</button>
<button type="button" class="js-zoom-out">Zoom Out</button>
</div>
<img id="image" src ="" style ="display:none">
</span>
</template>
Note: I will give 150 bounty points if someone gives me a solution.
Have a try with this code. @PranavNutalapati helped me figure this out.
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 on the click 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 - IGNORE this code
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
};
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.min(2, Math.max(0, 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.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
// sirpepole Add this
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);
// ends
return container;
};
}(jQuery));
// Zoom
//document.getElementById("img").src = json(data);
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;
}
<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>
I have added a data attribute id
to differentiate both the image's buttons.
Then, added a function to handle the button clicks (zoom_in
and zoom_out
namely).
function zoom_in(button) {
const id = $(button).parents('.pip').attr('data-id') // to retrieve the id
JQmasks[id].item.zoom(0.1); // to zoom the correct image
}
function zoom_out(button) {
const id = $(button).parents('.pip').attr('data-id')
JQmasks[id].item.zoom(-0.1);
}
Now, we need to handle the zoom functionality. For that, we need to create a new function zoom
within the container.
container.zoom = function (delta) {
settings.scale += delta; // increase / decrease the scale
settings.scale = Math.min(2, Math.max(0, settings.scale)) // limiting the range of the scale from 0 to 2
context.clearRect(0, 0, canvas.width, canvas.height); // clearing the whole canvas
container.drawMask(); // drawing the bow
container.drawImage(); // drawing the scaled image
}
We are only updating the scale property, so we need to make use of it while drawing it. So within the drawImage()
function
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); // translating the canvas to center of the image
context.scale(settings.scale, settings.scale); // scaling the canvas
context.translate(-(settings.x + img.width / 2), -(settings.y + img.height / 2)); // translating the canvas back to it's original position
let width = img.width, height = img.height;
context.drawImage(img, settings.x, settings.y, width, height);
context.restore();
initImage = false;
}
Starting with handling the button click.
function rotate_right(button) {
const id = $(button).parents('.pip').attr('data-id') // getting the id of the image
JQmasks[id].item.rotate(20); // rotating it by 20deg
}
function rotate_left(button) {
const id = $(button).parents('.pip').attr('data-id')
JQmasks[id].item.rotate(-20);
}
Now, inside the container, a new function rotate()
has been added to handle the rotation
container.rotate = function (rotation) {
settings.rotate += rotation * Math.PI / 180; // converting degree to radians and adding it to the previous rotation angle
console.log('Rotation', settings.rotate);
context.clearRect(0, 0, canvas.width, canvas.height); // clearing the canvas
container.drawMask(); // re-drawing the bow
container.drawImage(); // re-drawing the image
}
Here we are only updating the rotation property. So, while drawing it we need to use that. For that inside the drawImage()
function
context.save();
context.translate(settings.x + img.width / 2, settings.y + img.height / 2); // translating the canvas to the center of the image
context.rotate(settings.rotate); // rotating the image
context.scale(settings.scale, settings.scale); // scaling the image
context.translate(-(settings.x + img.width / 2), -(settings.y + img.height / 2)); // translating the image back to it's original position
let width = img.width, height = img.height;
context.drawImage(img, settings.x, settings.y, width, height);
context.restore();