Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用CropperJS旋转合适的画布_Javascript_Matrix_Rotation - Fatal编程技术网

Javascript 使用CropperJS旋转合适的画布

Javascript 使用CropperJS旋转合适的画布,javascript,matrix,rotation,Javascript,Matrix,Rotation,背景 我目前正在开发一种裁剪工具,它可以将图像与它要进入的元素相匹配。我得到的比率总是1:1,这意味着高度=宽度。一旦我从cropperJS得到了x,y,height,width,我就得到了这个比率,这个比率是图像要进入的元素的高度/宽度,并将图像的比特数加回来,使被裁剪的图像与它要进入的元素的比率相同 问题 我正在尝试为我的自定义裁剪器制作一个旋转工具,我从cropperJS获得的X,Y数据就好像图像从未旋转过一样。我已经创建了一个函数来进行矩阵旋转,以获得新的X,Y数据,我相信它工作正常。如

背景

我目前正在开发一种裁剪工具,它可以将图像与它要进入的元素相匹配。我得到的比率总是1:1,这意味着高度=宽度。一旦我从cropperJS得到了x,y,height,width,我就得到了这个比率,这个比率是图像要进入的元素的高度/宽度,并将图像的比特数加回来,使被裁剪的图像与它要进入的元素的比率相同

问题

我正在尝试为我的自定义裁剪器制作一个旋转工具,我从cropperJS获得的X,Y数据就好像图像从未旋转过一样。我已经创建了一个函数来进行矩阵旋转,以获得新的X,Y数据,我相信它工作正常。如果图像旋转180度,我的旋转画布的工具可以正常工作,但如果图像旋转270度或90度,则无法正常工作

代码

这里是计算矩阵旋转的较小函数,其中
x
y
是未旋转的坐标,
xm
ym
是旋转的中心点,
a
是旋转角度

function rotate(x, y, xm, ym, a) {
    var cos = Math.cos,
        sin = Math.sin,
        a = a * Math.PI / 180, // Convert to radians
        // Subtract midpoints, so that midpoint is translated to origin
        // and add it in the end again
        xr = (x - xm) * cos(a) - (y - ym) * sin(a) + xm,
        yr = (x - xm) * sin(a) + (y - ym) * cos(a) + ym;

    return [xr, yr];
}
这是进行裁剪的功能,它对0或180度的角度非常有效,但无法获得90或270度的正确坐标

var cropPhoto = async (imgSrc,cropData) =>{return new Promise((resolve, reject) => {
    var img = new Image()
    var ctx, canvas
    var ratio = cropData.ratio || 1
    var h = cropData.height
    var w = cropData.width
    var x = cropData.x
    var y = cropData.y
    if ( ratio > 1 ){
        var h = ratio * cropData.height
        y = y - ( (h - cropData.height) / 2 )
    }
    else if ( ratio < 1 ){
        var w = (1 / ratio) * cropData.width
        x = x - ( (w - cropData.width) / 2 )
    }
    img.style.transform = `${cropData.rotate}deg`
    img.src = imgSrc
    img.onload = () => {
        canvas = document.createElement("canvas")
        canvas.height = h
        canvas.width = w
        ctx = canvas.getContext('2d')
        if(cropData.rotate != 0){
            //nv == new values
            //this only works if its 180 degrees
            var nv = rotate(x,y, cropData.image.naturalWidth/2, cropData.image.naturalHeight/2, cropData.rotate)
            x = nv[0] - w
            y = nv[1] - h
        }
        ctx.drawImage(img, x, y, w, h, 0, 0, w, h)
        canvas = cropData.rotate != 0 ? drawRotated(cropData.rotate) : canvas
        canvas.toBlob(blob => {
            try {
                var urlCreator = window.URL || window.webkitURL;
                resolve(urlCreator.createObjectURL(blob))
            } catch (error) {
                reject()
            }
        },"image/png",1)
    }
    var drawRotated = degrees => {
        var newCanvas = document.createElement("canvas")
        if (  [90, 270].indexOf(Math.abs(degrees)) > -1 ){
            newCanvas.height = w
            newCanvas.width = h
        }else{
            newCanvas.height = h
            newCanvas.width = w
        }
        var ctx2 = newCanvas.getContext("2d")
        if ( [90,-270].indexOf(degrees) > -1 ){
            ctx2.translate( h  , 0 )
        }else if ( [-90,270].indexOf(degrees) > -1 ){
            ctx2.translate( 0  , w )
        }else if ( Math.abs(degrees) == 180 ){
            ctx2.translate( w , h )
        }
        ctx2.rotate(degrees*Math.PI/180)
        ctx2.drawImage(canvas, 0 , 0 )
        return newCanvas
    }
})}
我一直在绞尽脑汁想弄明白为什么图像没有得到90度或270度的坐标,但就是弄不明白为什么。我相信这与原始图像的纵横比有关,但我不确定


您可能只想使用库中的输出并以这种方式获取画布数据。在这种情况下,我娶了一个小CSS,得到了你想要的

cropper.getCroppedCanvas().toBlob()
这还为您提供了库的全部灵活性,因此(如图所示),您可以旋转任意角度,并执行库允许的任何其他操作

试试这个

您不使用CSS做这些事情有什么原因吗?
cropper.getCroppedCanvas().toBlob()