画布旋转未按预期工作

canvas rotate isn't working as expected

本文关键字:工作 布旋转 旋转      更新时间:2023-09-26

http://jsfiddle.net/s1n6cssa/12/

.HTML

<a href="#" id="rotate">Rotate</a>
<div id="print-region">
    <img class="overlay" src="http://www.itasveer.com/common/images/mobilecover/apple-5_5s.png" /> <span id="uploaded-image-container"></span>
    <img class="overlay" src="http://www.itasveer.com/common/images/mobilecover/apple-5_5s_white.png" />
</div>

.CSS

#myCanvas {
height: 100%;
width: 100%;
background-color: blue;
}
#print-region {
    height: 542px;
    width: 520px;
    margin: 0;
    position: relative;
    overflow: hidden;
}
.overlay {
    position: absolute;
    pointer-events: none;
}
#rotate {
    width: 100px;
    height: 30px;
}

JAVASCRIPT

var context;
var canvas;
var nHeight;  //the new height after resizing
var nWidth;   //the new width after resizing
var TO_RADIANS = Math.PI / 180;
var imageObj = new Image();
//USE ONLY ONE OF THE BELOW IMAGES AT A TIME
//square image which does not distort after rotation
imageObj.src = "https://i.stack.imgur.com/hwxO6.png";

//rectangular image which distorts after rotation
<!-- imageObj.src = "http://g-ecx.images-amazon.com/images/G/01/electronics/detail-page/Klipsch-Image-S4-II-Black-Lifestyle.jpg"; -->

var originalWidth = imageObj.width;
var originalHeight = imageObj.height;
$('#myCanvas').remove();

//used by context.rotate and updated after every rotation
$("#uploaded-image-container").attr({
    rotation: 0
});
$("#uploaded-image-container").append("<canvas id='myCanvas'></canvas>");

$("#uploaded-image-container").css({
    "position": "absolute",
        "height": originalHeight / 3, //one-third size of the original height of the uploaded image
        "width": originalWidth / 3,
        "top": $('#print-region').height() / 3,
        "left": $('#print-region').width() / 3
});
canvas = document.getElementById('myCanvas');
context = canvas.getContext('2d');
nHeight = canvas.height = originalHeight / 3;
nWidth = canvas.width = originalWidth / 3;

imageObj.onload = function () {
    context.drawImage(imageObj, 0, 0, originalWidth / 3, originalHeight / 3);
};
$("#uploaded-image-container").draggable({
    snap: false,
    scroll: false,
    cursor: "move",
    containment: '#print-region'
});

$("#uploaded-image-container").resizable({
    handles: 'nw, ne, sw, se',
    aspectRatio: true,
    containment: '#print-region',
    resize: function (e, ui) {
        nHeight = ui.size.height;
        nWidth = ui.size.width;
    }
});

$("#rotate").click(function () {
    updateRotation($("#uploaded-image-container"));
});

var imageRotation = 0; // the angle that the image is rotated
var updateRotation = function (elem) {
    var angle = parseInt(elem.attr('rotation'));
//after rotation, the nWidth and nHeight are interchanged hence temp variables
    var tempHeight, tempWidth;
    if (angle == 0) {
        imageRotation = 90;
        elem.attr('rotation', 90);
        tempHeight = nWidth;
        tempWidth = nHeight;
    } else if (angle == 90) {
        imageRotation = 180;
        elem.attr('rotation', 180);
        tempHeight = nHeight;
        tempWidth = nWidth;
    } else if (angle == 180) {
        imageRotation = 270;
        elem.attr('rotation', 270);
        tempHeight = nWidth;
        tempWidth = nHeight;
    } else {
        imageRotation = 0;
        elem.attr('rotation', 0);
        tempHeight = nHeight;
        tempWidth = nWidth;
    }
    $("#uploaded-image-container").css({
        "height": tempHeight,
            "width": tempWidth
    });
    canvas.width = tempWidth;
    canvas.height = tempHeight;
    context.translate(tempWidth / 2, tempHeight / 2);
    context.rotate(imageRotation * TO_RADIANS);
    context.translate(-tempWidth / 2, -tempHeight / 2);
    context.drawImage(imageObj, 0, 0, tempWidth, tempHeight);
};

我想使用 html2canvas 插件拍摄 jsfiddle 结果中显示的部分的快照。但是html2canvas不支持CSS3旋转属性。所以我使用画布来旋转图像,并且旋转被html2canvas成功捕获。

在上面的代码中,当我使用方形图像时,它可以完美旋转,但是当考虑矩形图像时,图像宽度和高度会失真。

调整大小、拖动和旋转的任何组合都不应扭曲图像。

问题出在哪里?

这是因为您在绘制和缩放图像时使用临时值(宽度和高度)作为方向。 然后方向的值应用于 setContainerHeight 和 setContainerWidth; 简而言之:您使用与坐标和缩放相同的值

我看不到您的第一张图片(在我的国家/地区被阻止),可能是因为它是正方形(宽度 = 高度); 因此没有问题发生,但矩形是宽度 = 2 * 高度; 所以使用图像比例。这应该适用于任何盒子形状

    var context;
    var canvas;
    var nHeight;
    var nWidth;
    var TO_RADIANS = Math.PI / 180;
    var imageObj = new Image();
     imageObj.src = "http://g-ecx.images-amazon.com/images/G/01/electronics/detail-page/Klipsch-Image-S4-II-Black-Lifestyle.jpg"; 

    var originalWidth = imageObj.width;
    var originalHeight = imageObj.height;
    $('#myCanvas').remove();
    $("#uploaded-image-container").attr({
        rotation: 0
    });
    $("#uploaded-image-container").append("<canvas id='myCanvas'></canvas>");

    $("#uploaded-image-container").css({
        "position": "absolute",
            "height": originalHeight / 3,
            "width": originalWidth / 3,
            "top": $('#print-region').height() / 3,
            "left": $('#print-region').width() / 3
    });
    canvas = document.getElementById('myCanvas');
    context = canvas.getContext('2d');
    nHeight = canvas.height ;
    nWidth = canvas.width ;

    imageObj.onload = function () {
        context.drawImage(imageObj, 0, 0, originalWidth / 3, originalHeight / 3);
    };
    $("#uploaded-image-container").draggable({
        snap: false,
        scroll: false,
        cursor: "move",
        containment: '#print-region'
    });

    $("#uploaded-image-container").resizable({
        handles: 'nw, ne, sw, se',
        aspectRatio: true,
        containment: '#print-region',
        resize: function (e, ui) {
            nHeight = ui.size.height;
            nWidth = ui.size.width;
        }
    });

    $("#rotate").click(function () {
        updateRotation($("#uploaded-image-container"));
    });
 var imageRotation = 0; // the angle that the image is rotated
var updateRotation = function (elem) {
    var angle = parseInt(elem.attr('rotation'));
    var ratio = nWidth/nHeight;
    var customX = nWidth, scaleX = nWidth;
    var customY = nHeight, scaleY = nHeight;
    var tempHeight, tempWidth;
    //the problem is in number 1 and 3 
    if (angle == 0) { //number 1
        imageRotation = 90;
        elem.attr('rotation', 90);
        tempHeight = nWidth;
        tempWidth = nHeight; customY = ratio*customY;
    } else if (angle == 90) { //number 2
        imageRotation = 180;
        elem.attr('rotation', 180);
        tempHeight = nHeight;
        tempWidth = nWidth ;
    } else if (angle == 180) {
        imageRotation = 270;
        elem.attr('rotation', 270);
        tempHeight = nWidth;
        tempWidth = nHeight;  customY = ratio*customY;
    } else { // number 4 handle 
        imageRotation = 0;
        elem.attr('rotation', 0);
        tempHeight = nHeight;
        tempWidth = nWidth;
    }
    $("#uploaded-image-container").css({
        "height": tempHeight,
        "width": tempWidth
    });
    canvas.width = customX;
    canvas.height = customY;
    context.translate(customX / 2, customY / 2);
    context.rotate(imageRotation * TO_RADIANS);
    context.translate( -customX / 2, -customY / 2);        
    context.drawImage(imageObj, 0, 0, customX, customY);
};

试试这个 http://jsfiddle.net/5hrx77nr/小提琴。

context.drawImage(imageObj, 0, 0, 100, 100 * imageObj.height / imageObj.width)

默认情况下,html5 将图像横向扩展到画布大小,因此您必须手动管理图像大小。

你应该多解释一下你想做什么。我认为轮换并没有那么复杂

无论如何。我在第 33、34 行发现了一个错误

nHeight = canvas.height = originalHeight / 3;
nWidth = canvas.width = originalWidth / 3;

也许你的意思是加法或乘法??因为更改后会出现蓝色画布并旋转。

    nHeight = canvas.height + originalHeight / 3;
    nWidth = canvas.width + originalWidth / 3;