如何解决旋转后“我的图片”未占据画布的整个宽度
所以我在画布上玩耍,我尝试旋转从设备硬盘加载的图像,如下所示:
class imageEdits {
constructor(canvas,imageSrc,canvasWidth,canvasHeight) {
this.canvas = canvas;
this.ctx = this.canvas.getContext("2d");
this.image = new Image();
this.image.src = imageSrc;
this.cWidth = canvasWidth;
this.cHeight = canvasHeight;
}
rotateImage = deg => {
this.ctx.save();
function degToRad(deg) {
return (1 / 57.3) * deg;
}
let imageHeight = this.image.naturalHeight,imageWidth = this.image.naturalWidth;
if (deg !== 0 && deg !== 180) {
imageHeight = this.image.naturalWidth;
imageWidth = this.image.naturalHeight;
} else {
(imageHeight = this.image.naturalHeight),(imageWidth = this.image.naturalWidth);
}
const {
canvasStyle: { height,width,scale,aspectRatio },} = this.computeAspectRatio(imageHeight,imageWidth);
console.log({ height,aspectRatio });
const halfWidth = width / 2;
const halfHeight = height / 2;
this.ctx.translate(halfWidth,halfHeight);
this.ctx.rotate(degToRad(deg));
this.canvas.style.transform = `scale3d(${scale},${scale},1)`;
this.canvas.style.backgroundColor = "rgb(0,0)";
this.canvas.style.transformOrigin = `top left`;
console.log({ width,height });
this.ctx.drawImage(this.image,-halfWidth,-halfHeight,height);
this.ctx.restore();
};
computeAspectRatio = (imageHeight,imageWidth) => {
const height = imageHeight;
const width = imageWidth;
(scale = 1),(canvasStyle = {});
this.canvas.width = width;
this.canvas.height = height;
const scaleX = this.cWidth / width;
const scaleY = this.cHeight / height;
if (scaleX > scaleY) scale = scaleY;
else scale = scaleX;
canvasStyle = { height,scale };
return { canvasStyle };
};
}
该代码的问题是,当我将图像旋转到其长宽比的倒数(即90度与180度)时,图像居中,并且不占用画布的整个宽度或高度。
here is a jsfiddle of the working code
但这是我得到的
请问有人看到我在做什么错吗?在此先感谢:)
解决方法
通常,通过将上下文平移到画布的中点,旋转上下文并最终在水平方向的宽度的负一半和垂直方向的高度的负一半处绘制图像,围绕中心进行旋转。
在您的情况下让事情变得更难的是,图像应始终填充整个画布,同时保持正确的纵横比。为此,我们需要知道给定角度下图像的确切宽度和高度,或更确切地说是边界框。幸运的是,我们只需要处理四个角度,因此就像您已经做的那样,只需将90°和270°的宽度和高度交换即可。
现在,我们知道图像的尺寸了,我们需要计算两个轴上的比例,并查看其中的哪一个不超过乘法后的画布宽度和高度。
然后使用此缩放比例缩放上下文,而不是用来缩放画布本身的css缩放比例。
这是一个基于您的代码的示例(只需单击“运行代码段”):
const canvas = document.getElementById("edit-canvas");
const ctx = canvas.getContext("2d");
const canvasWidth = 320;
const canvasHeight = 200;
let deg = 0;
let image;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
function degToRad(deg) {
return (1 / 57.3) * deg;
}
function draw() {
let scale,imageHeight,imageWidth,scaleX,scaleY;
if (deg != 0 && deg != 180) {
imageHeight = image.width;
imageWidth = image.height;
} else {
imageHeight = image.height;
imageWidth = image.width;
}
scaleX = canvasWidth / imageWidth;
scaleY = canvasHeight / imageHeight;
if (imageWidth * scaleX <= canvasWidth && imageHeight * scaleX <= canvasHeight) {
scale = scaleX;
} else {
scale = scaleY;
}
ctx.save();
ctx.clearRect(0,canvasWidth,canvasHeight);
ctx.translate(canvasWidth / 2,canvasHeight / 2);
ctx.rotate(degToRad(deg));
ctx.scale(scale,scale);
ctx.drawImage(image,-image.width / 2,-image.height / 2,image.width,image.height);
ctx.restore();
}
image = new Image();
image.onload = draw;
image.src = "https://picsum.photos/id/1079/300/200";
document.getElementById("rotate").addEventListener("click",() => {
deg += 90;
if (deg == 360) deg = 0;
draw();
});
<div class="canvas-container">
<input type="button" id="rotate" style="padding: 10px; font-size: 16px; position: absolute" value="Rotate" />
<canvas id="edit-canvas" style="border: 1px solid #000; margin-left: 10px;background-color: #c1f0c1;"></canvas>
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。