【问题标题】:how to rotate canvas context so that it fully fits the canvas area?如何旋转画布上下文以使其完全适合画布区域?
【发布时间】:2012-12-25 18:54:10
【问题描述】:

这是一个有点蹩脚的问题,因为我是画布的新手。我需要旋转放置在画布内的图像使其完全适合画布区域。在下面给出的代码 sn-p 中,图像旋转得很好,但我不知道如何使它适合画布矩形。我可以尝试使用三角函数的数学方法,但我认为它太复杂了:)


(来源:iconizer.net

var imgObj=new Image();
imgObj.src='people.jpg';
var width=128;//dynamic
var height=128;//dynamic


$(imgObj).load(function() {
    context.clearRect(0, 0, canvas.width, canvas.height);

    var rad = 30 * Math.PI / 180;

    context.translate(0 + width / 2, 0 + height / 2);

    context.rotate(rad);

    //draw the image    
    context.drawImage(imgObj,width / 2 * (-1),height / 2 * (-1),width,height);

    //reset the canvas  
    context.rotate(rad * ( -1 ) );
    context.translate((0 + width / 2) * (-1), (0 + height / 2) * (-1));
});

在 PHP 中很容易通过简单地将旋转后的图像放置在所需坐标上,但在画布中并非如此。请帮忙:)

【问题讨论】:

    标签: html canvas rotation


    【解决方案1】:

    这是你要找的吗:

    var newCanvas = document.createElement('canvas');
    newCanvas.height="175";
    newCanvas.width="175";
    newCanvas.style.border="1px solid black";
    document.body.appendChild(newCanvas);
    
    var imgObj=new Image();
    imgObj.src='people.jpg';
    var width=imgObj.width;
    var height=imgObj.height;
    
    var angleToRotate = 30 * Math.PI / 180;
    
    var requiredCanvasHeight = Math.sin(angleToRotate)*width+Math.cos(angleToRotate)*height;
    var requiredCanvasWidth = Math.sin(angleToRotate)*height+Math.cos(angleToRotate)*width;
    newCanvas.height=Math.ceil(requiredCanvasHeight);
    newCanvas.width=Math.ceil(requiredCanvasWidth);
    
    $(imgObj).load(function() {
        var context = newCanvas.getContext('2d');
    
        context.clearRect(0, 0, newCanvas.width, newCanvas.height);
    
        context.translate(0 + width / 2, 0);// + height / 2);
    
        context.rotate(angleToRotate);
    
        //draw the image    
        context.drawImage(imgObj, 0, 0, width, height);
    
        //reset the canvas  
        context.rotate(rad * ( -1 ) );
        context.translate((0 + width / 2) * (-1), (0 + height / 2) * (-1));
    });
    

    你不需要在drawImage方法调用中偏移图像。

    【讨论】:

    • 不。那不是我想要的。如果旋转后的图像尺寸小于画布尺寸,我需要自动调整图像大小以适合画布矩形。旋转本身很好。它正确放置图像。它只是没有按照应有的方式调整大小。
    • 为此,您可以使用三角函数进行计算。在这里摆弄 - jsfiddle.net/poonia/3tPsc
    • 这个不错,谢谢。但是 - 这仍然不是我需要的。首先 - 它不适用于 30 以外的其他角度(我尝试了 45 和 60)。其次 - 给定的公式会增加画布的大小,而我需要调整内部图像的大小以适合画布。并且画布不必是原始图像的大小。它可能更小并且是固定的。
    【解决方案2】:

    自己解决了这个问题。虽然,它有点自满。如果有人找到更优化的解决方案,它会真正帮助我:)

        $(document).ready(function(){
        var canvas=document.getElementById('iconCanvas');//<canvas id="iconCanvas" width="128" height="128"></canvas>
        var context=canvas.getContext("2d");
        var imgObj=new Image();
        imgObj.src='/images/temp/kdmconfig.png';
        var iconWidth=128;
        var iconHeight=128;
        var width=200;
        var height=128;
        var angleToRotate=30;
    
    
        $(imgObj).load(function() {
            context.clearRect(0, 0, canvas.width, canvas.height);
    
            var rad = angleToRotate * Math.PI / 180;
            var newAngle=angleToRotate;
    
            //in case angle is >90
            if(newAngle>90 && newAngle<=180){
                newAngle=180-newAngle;
            }
            else if(newAngle>180 && newAngle<=270){
                newAngle=270-newAngle;
            }
            else if(newAngle>270){
                newAngle=360-newAngle;
            }
    
            context.translate(0 + iconWidth / 2, 0 + iconWidth / 2);
    
            context.rotate(rad);
    
            //draw the image
    
            if(width>height){
                var newImageHeight=Math.round((Math.cos((Math.atan(iconWidth/iconHeight)*180/Math.PI)*Math.PI/180)*height)/Math.sin((parseInt(90-newAngle)+Math.atan(iconWidth/iconHeight)*180/Math.PI)*Math.PI/180));
    
                var newImageWidth=Math.round(newImageHeight*iconWidth/iconHeight);
            }
            else{
                var newImageWidth=Math.round((Math.cos((Math.atan(iconHeight/iconWidth)*180/Math.PI)*Math.PI/180)*width)/Math.sin((parseInt(90-newAngle)+Math.atan(iconHeight/iconWidth)*180/Math.PI)*Math.PI/180));
    
                var newImageHeight=Math.round(newImageWidth*iconHeight/iconWidth);
            }
    
    
            context.drawImage(imgObj,newImageWidth / 2 * (-1),newImageHeight / 2 * (-1),newImageWidth,newImageHeight);
    
        });
        });
    

    【讨论】:

      猜你喜欢
      • 2014-12-29
      • 1970-01-01
      • 2019-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 2015-02-07
      • 2013-04-06
      相关资源
      最近更新 更多