【问题标题】:canvas rotate isn't working as expected画布旋转未按预期工作
【发布时间】:2015-01-11 23:12:09
【问题描述】:

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 = "http://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 的旋转属性。 于是我用canvas来旋转图片,旋转被html2canvas成功捕获。

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

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

有什么问题?

【问题讨论】:

    标签: javascript html canvas rotation


    【解决方案1】:

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

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

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

    【讨论】:

    • 非常感谢。我不能投票,因为我需要 15 声望。当我达到那个声誉时,我会投票。 :)
    【解决方案2】:

    你应该多解释一下你想做什么。我觉得轮换没那么复杂

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

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

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

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

    【讨论】:

    • 我已经编辑了帖子,并提供了更多解释。蓝色只是为了检查旋转后画布的区域。如果图像正确旋转,我们不应该看到蓝色背景。让我也将 cmets 添加到代码中。
    • 你的意思是当我点击旋转时,另一个带有图片旋转90的画布出现在它的底部。??原图是旋转还是静止?
    • 我的意思是如果你只是想旋转图像以供其他插件使用.. 只需 1.create canvas; 2.context.drawImage(img.jpg) /*在画布中插入jpg*/ 3.context.rotate();
    • 同一张图片应该旋转。另外,如果原始图像被旋转,那么它可以工作,但我希望所有功能都可以在图像的缩放版本上工作。
    【解决方案3】:

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

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

    默认情况下 html5 将图片缩放到画布大小,因此您必须手动管理图片大小。

    【讨论】:

    • jsfiddle.net/5hrx77nr/1 我已经在你的分叉代码中评论了第一张图片。没有进行任何其他更改。它不工作。
    猜你喜欢
    • 2017-02-17
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 2018-08-03
    • 2021-10-19
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多