Divan Linnow
Divan Linnow

Reputation: 31

HTML canvas drawImage not working correctly for landscape images

I'm developing a mobile app in angular using ionic framework. I have the following function for displaying images. This works fine for drawing and scaling for portrait images, but landscape images seem a bit...cut off. Any ideas?

$scope.drawBackground = function (imageUri) {
        var context = canvas.getContext("2d");
        var img = new Image();
        img.src = imageUri;
        img.onload = function () {
            var orientation = "portrait";
            if (img.naturalWidth > img.naturalHeight) {
                orientation = "landscape";
            }
            canvas.width = orientation == "landscape" ? window.innerHeight : window.innerWidth;
            canvas.height = orientation == "landscape" ? window.innerWidth : window.innerHeight;
            var hRatio = canvas.width / img.width;
            var vRatio = canvas.height / img.height;
            var ratio = Math.min(hRatio, vRatio);
            var center_X = (canvas.width - img.width * ratio) / 2;
            var center_Y = (canvas.height - img.height * ratio) / 2;
            context.clearRect(0, 0, canvas.width, canvas.height);
            if (orientation == "landscape") {
                context.translate(window.innerWidth, 0);
                context.rotate(90 * Math.PI / 180);
            }
            context.drawImage(img, 0, 0, img.width, img.height, center_X, center_Y, img.width * ratio, img.height * ratio);
        };
    };

Upvotes: 3

Views: 869

Answers (1)

Blindman67
Blindman67

Reputation: 54026

You are rotating the canvas coordinate system with context.rotate(90 * Math.PI / 180);so when you draw the image the width is in the screen height direction and height in the negative screen width direction, also the center x and y coordinates are switched. Change your code to take the this into account to solve your problem.

BTW context.rotate(90 * Math.PI / 180); 90 goes into 180 two times so it becomes context.rotate(1 * Math.PI / 2); multiplying by 1 does nothing so it becomes context.rotate(Math.PI / 2); saving a multiplication. Using radians is always better 360 == Math.PI*2, 180 == Math.PI and as shown 90 == Math.PI/2

Upvotes: 3

Related Questions