如何在固定 canvas 中绘制缩放图像并在其中心旋转?
How can I draw a scaled image in a fixed canvas and rotate it in its center?
我有一个固定宽度和高度的 canvas,我想在 canvas 上绘制一个 scaled/fitted 图像并在其中心旋转图像。当我在 angle 中放置 0 以外的任何值时,图像不居中并且偏离 canvas.
这是我现在拥有的:
const box = document.getElementById("box");
const box2 = document.getElementById("box2");
(function() {
const image = new Image();
image.onload = () => {
const myCanvas = drawImage(0, image);
const img = document.createElement("img");
img.src = myCanvas.toDataURL("image/png", 1);
img.style = "border: 1px solid black;";
box.append(img)
const myCanvas2 = drawImage(15, image);
const img2 = document.createElement("img");
img2.src = myCanvas2.toDataURL("image/png", 1);
img2.style = "border: 1px solid black;";
box2.append(img2)
};
image.src = "https://raw.githubusercontent.com/hamza-ameer/Google-Maps-SmoothCarAnimation/Uodated/car_marker.png";
image.crossOrigin="anonymous"
})()
function drawImage(angle, image) {
const canvasWidth = 100;
const canvasHeight = 100;
const myCanvas = document.createElement("canvas");
myCanvas.width = canvasWidth;
myCanvas.height = canvasHeight;
const context = myCanvas.getContext("2d");
const imageWidth = image.width;
const imageHeight = image.height;
const scaler = scalePreserveAspectRatio(imageWidth, imageHeight, canvasWidth, canvasHeight);
const scaledWidth = imageWidth * scaler;
const scaledHeight = imageHeight * scaler;
context.save();
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.rotate((angle * Math.PI) / 180);
context.translate((canvasWidth - scaledWidth) / 2, (canvasHeight - scaledHeight) / 2);
context.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, scaledWidth, scaledHeight);
context.strokeRect(0, 0, imageWidth * scaler, imageHeight * scaler);
context.restore();
return myCanvas;
}
function scalePreserveAspectRatio(imgW, imgH, maxW, maxH) {
return Math.min(maxW / imgW, maxH / imgH);
}
<div id="box"></div>
<div id="box2"></div>
感谢您的帮助。
你只需要在使用context.rotate
之前使用context.translate
将原点(旋转点)设置为中心,然后再重新设置。
const box = document.getElementById("box");
const box2 = document.getElementById("box2");
(function() {
const image = new Image();
image.onload = () => {
const myCanvas = drawImage(0, image);
const img = document.createElement("img");
img.src = myCanvas.toDataURL("image/png", 1);
img.style = "border: 1px solid black;";
box.append(img)
const myCanvas2 = drawImage(15, image);
const img2 = document.createElement("img");
img2.src = myCanvas2.toDataURL("image/png", 1);
img2.style = "border: 1px solid black;";
box2.append(img2)
};
image.src = "https://raw.githubusercontent.com/hamza-ameer/Google-Maps-SmoothCarAnimation/Uodated/car_marker.png";
image.crossOrigin="anonymous"
})()
function drawImage(angle, image) {
const canvasWidth = 100;
const canvasHeight = 100;
const myCanvas = document.createElement("canvas");
myCanvas.width = canvasWidth;
myCanvas.height = canvasHeight;
const context = myCanvas.getContext("2d");
const imageWidth = image.width;
const imageHeight = image.height;
const scaler = scalePreserveAspectRatio(imageWidth, imageHeight, canvasWidth, canvasHeight);
const scaledWidth = imageWidth * scaler;
const scaledHeight = imageHeight * scaler;
context.save();
context.clearRect(0, 0, canvasWidth, canvasHeight);
//set origin at center
context.translate((canvasWidth - scaledWidth) / 2, (canvasHeight - scaledHeight) / 2);
context.rotate((angle * Math.PI) / 180);
//restore origin to left-top corner
context.translate(-(canvasWidth - scaledWidth) / 2, -(canvasHeight - scaledHeight) / 2);
context.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, scaledWidth, scaledHeight);
context.strokeRect(0, 0, imageWidth * scaler, imageHeight * scaler);
context.restore();
return myCanvas;
}
function scalePreserveAspectRatio(imgW, imgH, maxW, maxH) {
return Math.min(maxW / imgW, maxH / imgH);
}
<div id="box"></div>
<div id="box2"></div>
要将原点设置在对象的中心,您可以在 -objectsWidth/2
和 -objectsHeight/2
处绘制对象。这会将 canvas 的原点 (0,0) 放在对象中心。现在您可以在 canvas 上任意位置翻译对象。请记住,当您翻译时,您正在将 canvas 的 (0,0) 坐标移动到特定位置。
请记住,我故意没有改变笔划的原点,因为我想让你看到不同之处。然而,你会做同样的事情并用 -objectsWidth/2
和 -objectsHeight/2
.
绘制它
context.strokeRect(-scaledWidth/2, -scaledHeight/2, imageWidth * scaler, imageHeight * scaler);
这是放置项目并将原点设置为中心的最简单方法。顺便说一句,您之后不需要翻译回来。这就是使用 save()
和 restore()
的意义所在
const box = document.getElementById("box");
const box2 = document.getElementById("box2");
(function() {
const image = new Image();
image.onload = () => {
const myCanvas = drawImage(0, image);
const img = document.createElement("img");
img.src = myCanvas.toDataURL("image/png", 1);
img.style = "border: 1px solid black;";
box.append(img)
const myCanvas2 = drawImage(15, image);
const img2 = document.createElement("img");
img2.src = myCanvas2.toDataURL("image/png", 1);
img2.style = "border: 1px solid black;";
box2.append(img2)
};
image.src = "https://raw.githubusercontent.com/hamza-ameer/Google-Maps-SmoothCarAnimation/Uodated/car_marker.png";
image.crossOrigin="anonymous"
})()
function drawImage(angle, image) {
const canvasWidth = 100;
const canvasHeight = 100;
const myCanvas = document.createElement("canvas");
myCanvas.width = canvasWidth;
myCanvas.height = canvasHeight;
const context = myCanvas.getContext("2d");
const imageWidth = image.width;
const imageHeight = image.height;
const scaler = scalePreserveAspectRatio(imageWidth, imageHeight, canvasWidth, canvasHeight);
const scaledWidth = imageWidth * scaler;
const scaledHeight = imageHeight * scaler;
context.save();
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.translate(canvasWidth/2, canvasHeight/2);
context.rotate((angle * Math.PI) / 180);
context.drawImage(image, 0, 0, imageWidth, imageHeight, -scaledWidth/2, -scaledHeight/2, scaledWidth, scaledHeight);
context.strokeRect(0, 0, imageWidth * scaler, imageHeight * scaler);
context.restore();
return myCanvas;
}
function scalePreserveAspectRatio(imgW, imgH, maxW, maxH) {
return Math.min(maxW / imgW, maxH / imgH);
}
<div id="box"></div>
<div id="box2"></div>
我有一个固定宽度和高度的 canvas,我想在 canvas 上绘制一个 scaled/fitted 图像并在其中心旋转图像。当我在 angle 中放置 0 以外的任何值时,图像不居中并且偏离 canvas.
这是我现在拥有的:
const box = document.getElementById("box");
const box2 = document.getElementById("box2");
(function() {
const image = new Image();
image.onload = () => {
const myCanvas = drawImage(0, image);
const img = document.createElement("img");
img.src = myCanvas.toDataURL("image/png", 1);
img.style = "border: 1px solid black;";
box.append(img)
const myCanvas2 = drawImage(15, image);
const img2 = document.createElement("img");
img2.src = myCanvas2.toDataURL("image/png", 1);
img2.style = "border: 1px solid black;";
box2.append(img2)
};
image.src = "https://raw.githubusercontent.com/hamza-ameer/Google-Maps-SmoothCarAnimation/Uodated/car_marker.png";
image.crossOrigin="anonymous"
})()
function drawImage(angle, image) {
const canvasWidth = 100;
const canvasHeight = 100;
const myCanvas = document.createElement("canvas");
myCanvas.width = canvasWidth;
myCanvas.height = canvasHeight;
const context = myCanvas.getContext("2d");
const imageWidth = image.width;
const imageHeight = image.height;
const scaler = scalePreserveAspectRatio(imageWidth, imageHeight, canvasWidth, canvasHeight);
const scaledWidth = imageWidth * scaler;
const scaledHeight = imageHeight * scaler;
context.save();
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.rotate((angle * Math.PI) / 180);
context.translate((canvasWidth - scaledWidth) / 2, (canvasHeight - scaledHeight) / 2);
context.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, scaledWidth, scaledHeight);
context.strokeRect(0, 0, imageWidth * scaler, imageHeight * scaler);
context.restore();
return myCanvas;
}
function scalePreserveAspectRatio(imgW, imgH, maxW, maxH) {
return Math.min(maxW / imgW, maxH / imgH);
}
<div id="box"></div>
<div id="box2"></div>
感谢您的帮助。
你只需要在使用context.rotate
之前使用context.translate
将原点(旋转点)设置为中心,然后再重新设置。
const box = document.getElementById("box");
const box2 = document.getElementById("box2");
(function() {
const image = new Image();
image.onload = () => {
const myCanvas = drawImage(0, image);
const img = document.createElement("img");
img.src = myCanvas.toDataURL("image/png", 1);
img.style = "border: 1px solid black;";
box.append(img)
const myCanvas2 = drawImage(15, image);
const img2 = document.createElement("img");
img2.src = myCanvas2.toDataURL("image/png", 1);
img2.style = "border: 1px solid black;";
box2.append(img2)
};
image.src = "https://raw.githubusercontent.com/hamza-ameer/Google-Maps-SmoothCarAnimation/Uodated/car_marker.png";
image.crossOrigin="anonymous"
})()
function drawImage(angle, image) {
const canvasWidth = 100;
const canvasHeight = 100;
const myCanvas = document.createElement("canvas");
myCanvas.width = canvasWidth;
myCanvas.height = canvasHeight;
const context = myCanvas.getContext("2d");
const imageWidth = image.width;
const imageHeight = image.height;
const scaler = scalePreserveAspectRatio(imageWidth, imageHeight, canvasWidth, canvasHeight);
const scaledWidth = imageWidth * scaler;
const scaledHeight = imageHeight * scaler;
context.save();
context.clearRect(0, 0, canvasWidth, canvasHeight);
//set origin at center
context.translate((canvasWidth - scaledWidth) / 2, (canvasHeight - scaledHeight) / 2);
context.rotate((angle * Math.PI) / 180);
//restore origin to left-top corner
context.translate(-(canvasWidth - scaledWidth) / 2, -(canvasHeight - scaledHeight) / 2);
context.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, scaledWidth, scaledHeight);
context.strokeRect(0, 0, imageWidth * scaler, imageHeight * scaler);
context.restore();
return myCanvas;
}
function scalePreserveAspectRatio(imgW, imgH, maxW, maxH) {
return Math.min(maxW / imgW, maxH / imgH);
}
<div id="box"></div>
<div id="box2"></div>
要将原点设置在对象的中心,您可以在 -objectsWidth/2
和 -objectsHeight/2
处绘制对象。这会将 canvas 的原点 (0,0) 放在对象中心。现在您可以在 canvas 上任意位置翻译对象。请记住,当您翻译时,您正在将 canvas 的 (0,0) 坐标移动到特定位置。
请记住,我故意没有改变笔划的原点,因为我想让你看到不同之处。然而,你会做同样的事情并用 -objectsWidth/2
和 -objectsHeight/2
.
context.strokeRect(-scaledWidth/2, -scaledHeight/2, imageWidth * scaler, imageHeight * scaler);
这是放置项目并将原点设置为中心的最简单方法。顺便说一句,您之后不需要翻译回来。这就是使用 save()
和 restore()
const box = document.getElementById("box");
const box2 = document.getElementById("box2");
(function() {
const image = new Image();
image.onload = () => {
const myCanvas = drawImage(0, image);
const img = document.createElement("img");
img.src = myCanvas.toDataURL("image/png", 1);
img.style = "border: 1px solid black;";
box.append(img)
const myCanvas2 = drawImage(15, image);
const img2 = document.createElement("img");
img2.src = myCanvas2.toDataURL("image/png", 1);
img2.style = "border: 1px solid black;";
box2.append(img2)
};
image.src = "https://raw.githubusercontent.com/hamza-ameer/Google-Maps-SmoothCarAnimation/Uodated/car_marker.png";
image.crossOrigin="anonymous"
})()
function drawImage(angle, image) {
const canvasWidth = 100;
const canvasHeight = 100;
const myCanvas = document.createElement("canvas");
myCanvas.width = canvasWidth;
myCanvas.height = canvasHeight;
const context = myCanvas.getContext("2d");
const imageWidth = image.width;
const imageHeight = image.height;
const scaler = scalePreserveAspectRatio(imageWidth, imageHeight, canvasWidth, canvasHeight);
const scaledWidth = imageWidth * scaler;
const scaledHeight = imageHeight * scaler;
context.save();
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.translate(canvasWidth/2, canvasHeight/2);
context.rotate((angle * Math.PI) / 180);
context.drawImage(image, 0, 0, imageWidth, imageHeight, -scaledWidth/2, -scaledHeight/2, scaledWidth, scaledHeight);
context.strokeRect(0, 0, imageWidth * scaler, imageHeight * scaler);
context.restore();
return myCanvas;
}
function scalePreserveAspectRatio(imgW, imgH, maxW, maxH) {
return Math.min(maxW / imgW, maxH / imgH);
}
<div id="box"></div>
<div id="box2"></div>