0

We gave an option for user to Upload the image

Also we are displaying Rotate button on top....

Requirement :

Onclick Rotate button , Image should rotate 90 degress as Here....

Issue :

Image is rotating randomly : Video link

Below is Code Snippet :

$(document).ready(function() {

    //  base64string image format- to work in codepen, fiddle
 
    var maskedImageUrla = "https://i.imgur.com/TZwOgSa.png";
   
   // maskedImage 
    var mask1 = $(".container").mask({
        maskImageUrl: maskedImageUrla,
        onMaskImageCreate: function(img) {
            // add your style to the img example below
            img.css({
                "left": 105,
                "top": 5,
    "id": 'self'
            })
        }
    });

    fileupa1.onchange = function() {
        mask1.loadImage(URL.createObjectURL(fileupa1.files[0]));
    };
    
// Rotation code : 

let imageToSpin = document.getElementById('self');

var r = 0;
function spinImage() {
r+= 10;
 mask1.rotate(r) ;
}

btnTotate.onclick =spinImage;
    
}); // end of document ready

// jq code 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() + JQmasks.length,
            x: 0, // image start position
            y: 0, // image start position
            onImageCreate: function(img) {},
            onMaskImageCreate: function(div) {},
            rotate: 0, // rotation
        }, options);

        var container = {};

        let prevX = 0,
            prevY = 0,
            draggable = false,
            img,
            canvas,
            context,
            image,
            initImage = false,
            startX = settings.x,
            startY = settings.y,
            div,
            rotate=settings.rotate,
            obj = $(this);
                              
        container.updateStyle = function() {

            context.clearRect(0, 0, canvas.width, canvas.height);
            context.globalCompositeOperation = "source-over";

            if (initImage || !image) {
                image = new Image();
                image.setAttribute('crossOrigin', 'anonymous');
                image.src = settings.maskImageUrl;
                image.onload = function() {
                    if (settings.onImageCreate)
                        settings.onImageCreate(image);

                    canvas.width = image.width * settings.scale;
                    canvas.height = image.height * settings.scale;
                    context.drawImage(image, 0, 0, image.width, image.height);
                    div.css({
                        "width": image.width,
                        "height": image.height
                    });
                };
            } else {
            // rotate the canvas to the specified degrees
             
                context.drawImage(image, 0, 0, image.width, image.height);
                
            }
             context.save();
             context.rotate(rotate);
            if (initImage || !img) {
                img = new Image();
                img.src = settings.imageUrl || "";
                img.setAttribute('crossOrigin', 'anonymous');
                img.onload = function() {
                    settings.x = settings.x === 0 && initImage === true ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
                    settings.y = settings.y === 0 && initImage === true ? (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;
                };
            } else {
                context.globalCompositeOperation = 'source-atop';
                context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
            }
          
              context.restore();
        };

        // Rotation code : 

        container.rotate =function(r){
        rotate= r;
        container.updateStyle();
        }

        // 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();
        };

        container.createCanvas = function() {
            if (canvas)
                canvas.remove();
            canvas = document.createElement("canvas");
            context = canvas.getContext('2d');
            canvas.setAttribute("draggable", "true");
            canvas.setAttribute("id", settings.id);
            div.append(canvas);
            div.find("canvas").hover(container.selected);
            div.find("canvas").on('touchstart mousedown', container.selected);
            div.find("canvas").on('touchend mouseup', function(event) {
                if (event.handled === true) return;
                event.handled = true;
                JQmasks.forEach(function(item) {
                    
                });
            });
            div.find("canvas").bind("dragover", container.onDragOver);
        };

        // change the masked Image
        container.loadMaskImage = function(imageUrl, from) {
            if (div)
                div.remove();

            settings.maskImageUrl = imageUrl;
            div = $("<div/>", {
                "class": "masked-img"
            });
            container.createCanvas();
            obj.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: pink;
}

.container canvas {
    display: block;
}

.masked-img {
    overflow: hidden;
    margin-left: 10px;
    position: relative;
}

.rotated {
  transform: rotate(90deg)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>

<input type="button" id="btnTotate" value="Rotate"/>

<br/><hr>

image 1 
<input id="fileupa1"  type="file" >

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

Here is CodePen

Please let me know if you need more information....

2 Answers2

0

I can suggest to have imagemagick installed on the server then run the mogrify command which is part of imagemagick as a shell command. Here are examples of how to run a shell command.

Read the mogrify man page for syntax on rotating images.

Felicia
  • 41
  • 4
0

The rotate function on canvas context accepts angle in radians and not degrees.

If you have to convert the degrees to radians, use this radians = degree * Math.PI / 180

Now, even by doing this you will be rotating the image from the top left corner. If you have to prevent this and rotate it from the centre, you need to translate the canvas to its centre. You can achieve that by

context.save()
context.translate(canvas.width / 2, canvas.height / 2)
context.rotate(rotate)
context.translate(-canvas.width / 2, -canvas.height / 2)
context.restore()

This will rotate the image from the centre of the canvas. If you want to rotate the image from the centre of the image calculate the midpoint of the image and replace the coordinates in the translate function.

$(document).ready(function() {

    //  base64string image format- to work in codepen, fiddle
 
    var maskedImageUrla = "https://i.imgur.com/TZwOgSa.png";
   
   // maskedImage 
    var mask1 = $(".container").mask({
        maskImageUrl: maskedImageUrla,
        onMaskImageCreate: function(img) {
            // add your style to the img example below
            img.css({
                "left": 105,
                "top": 5,
    "id": 'self'
            })
        }
    });

    fileupa1.onchange = function() {
        mask1.loadImage(URL.createObjectURL(fileupa1.files[0]));
    };
    
// Rotation code : 

let imageToSpin = document.getElementById('self');

var r = 0;
function spinImage() {
r+= 10;
 mask1.rotate(r) ;
}

btnTotate.onclick =spinImage;
    
}); // end of document ready

// jq code 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() + JQmasks.length,
            x: 0, // image start position
            y: 0, // image start position
            onImageCreate: function(img) {},
            onMaskImageCreate: function(div) {},
            rotate: 0, // rotation
        }, options);

        var container = {};

        let prevX = 0,
            prevY = 0,
            draggable = false,
            img,
            canvas,
            context,
            image,
            initImage = false,
            startX = settings.x,
            startY = settings.y,
            div,
            rotate=settings.rotate,
            obj = $(this);
                              
        container.updateStyle = function() {

            context.clearRect(0, 0, canvas.width, canvas.height);
            context.globalCompositeOperation = "source-over";

            if (initImage || !image) {
                image = new Image();
                image.setAttribute('crossOrigin', 'anonymous');
                image.src = settings.maskImageUrl;
                image.onload = function() {
                    if (settings.onImageCreate)
                        settings.onImageCreate(image);

                    canvas.width = image.width * settings.scale;
                    canvas.height = image.height * settings.scale;
                    context.drawImage(image, 0, 0, image.width, image.height);
                    div.css({
                        "width": image.width,
                        "height": image.height
                    });
                };
            } else {
            // rotate the canvas to the specified degrees
             
                context.drawImage(image, 0, 0, image.width, image.height);
                
            }
             context.save();
             context.translate(canvas.width / 2, canvas.height / 2);
             context.rotate(rotate);
             context.translate(-canvas.width / 2, -canvas.height / 2);
            if (initImage || !img) {
                img = new Image();
                img.src = settings.imageUrl || "";
                img.setAttribute('crossOrigin', 'anonymous');
                img.onload = function() {
                    settings.x = settings.x === 0 && initImage === true ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
                    settings.y = settings.y === 0 && initImage === true ? (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;
                };
            } else {
                context.globalCompositeOperation = 'source-atop';
                context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
            }
          
              context.restore();
        };

        // Rotation code : 

        container.rotate =function(r){
        rotate= r*Math.PI/180;
        container.updateStyle();
        }

        // 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();
        };

        container.createCanvas = function() {
            if (canvas)
                canvas.remove();
            canvas = document.createElement("canvas");
            context = canvas.getContext('2d');
            canvas.setAttribute("draggable", "true");
            canvas.setAttribute("id", settings.id);
            div.append(canvas);
            div.find("canvas").hover(container.selected);
            div.find("canvas").on('touchstart mousedown', container.selected);
            div.find("canvas").on('touchend mouseup', function(event) {
                if (event.handled === true) return;
                event.handled = true;
                JQmasks.forEach(function(item) {
                    
                });
            });
            div.find("canvas").bind("dragover", container.onDragOver);
        };

        // change the masked Image
        container.loadMaskImage = function(imageUrl, from) {
            if (div)
                div.remove();

            settings.maskImageUrl = imageUrl;
            div = $("<div/>", {
                "class": "masked-img"
            });
            container.createCanvas();
            obj.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: pink;
}

.container canvas {
    display: block;
}

.masked-img {
    overflow: hidden;
    margin-left: 10px;
    position: relative;
}

.rotated {
  transform: rotate(90deg)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>

<input type="button" id="btnTotate" value="Rotate"/>

<br/><hr>

image 1 
<input id="fileupa1"  type="file" >

<div class="container">
</div>
Advaith
  • 2,490
  • 3
  • 21
  • 36
  • @vickeycolors this code only rotates the image by 10deg because you are only updating by 10. If you want to rotate it by 90deg change 10 to 90 – Advaith May 07 '19 at 07:08
  • Thanks a lot, it worked fine.... can you please help me to make it dynamic , means getting solution for two images : https://codepen.io/kidsdial/pen/mYygLP –  May 07 '19 at 07:15
  • @vickeycolors you can use two variables to store the rotation angle of two images – Advaith May 07 '19 at 07:17