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