Codepen:https://codepen.io/anon/pen/XEYEKd
问题:给定在一个画布上渲染的场景,我需要应用哪些变换才能使第一个画布上的点(x1,y1已知)处于某个固定点上将旋转应用于画布1的图像/场景后,第二个画布(x2,y2已知,但相对于第二个画布,而不是相对于第一个画布)。
请参阅上面的codepen以了解要使用的游乐场。尝试让红点在视口中居中。操纵旋转(degrees
变量)和p.x
以及p.y
为任意值,并测试您的转换代码是否仍然有效(将红点保持在视口中间)
我尝试过一系列应用罪,cos,逆sin,逆cos和毕达哥拉斯定理的东西,但没有取得任何成功。
答案 0 :(得分:1)
您需要的是定义您在drawImage
中使用的源坐标。
这些坐标是你的指针编号的负值+目标画布大小的一半,因此无论它在源画布上的哪个位置,都会在目标画布的中心绘制该点。
一旦你得到它,你所要做的就是应用基本的
translate(center, center);
rotate(angle);
drawImage(img, -center, -center);
function draw() {
const scene = document.getElementById('canvas-scene')
const ctx1 = scene.getContext('2d')
const viewport = document.getElementById('canvas-viewport')
const ctx2 = viewport.getContext('2d')
const p = {
x: (Math.random() * (ctx1.canvas.width - 20)) + 10,
y: (Math.random() * (ctx1.canvas.height - 20)) + 10,
};
const radians = (Math.PI *2 * Math.random());
let img = new Image();
img.src = 'http://www.mngeo.state.mn.us/chouse/images/sibley_shillinglake_nc.jpg'
img.onload = function() {
ctx1.drawImage(img, 0, 0)
ctx1.fillStyle = 'red'
ctx1.fillRect(p.x - 5, p.y - 5, 10, 10);
// get destination width and height
const cw = ctx2.canvas.width,
ch = ctx2.canvas.height,
// new coords are the negative of our point coords + half the width of our new canvas
newX = (p.x * -1) + cw/2,
newY = (p.y * -1) + ch/2;
// move to canvas center
ctx2.translate(cw / 2, ch / 2);
ctx2.rotate(radians);
// draw by translating back to the top left corner
ctx2.drawImage(scene, newX - cw/2, newY - ch/2);
}
}
draw();

#canvas-viewport {
border: 1px solid black;
margin-bottom: 40px;
}

<h3>Viewport</h3>
<canvas id="canvas-viewport" width="256" height="128"></canvas>
<h3>Scene</h3>
<canvas id="canvas-scene" width="512" height="512"></canvas>
&#13;
答案 1 :(得分:0)
我得到了它的工作:https://codepen.io/anon/pen/Koeoxd
原则上根本不需要三角法。
function draw() {
const scene = document.getElementById('canvas-scene')
const ctx1 = scene.getContext('2d')
const viewport = document.getElementById('canvas-viewport')
const ctx2 = viewport.getContext('2d')
let img = new Image();
img.src = 'http://www.mngeo.state.mn.us/chouse/images/sibley_shillinglake_nc.jpg'
const p = {
x: 150,
y: 200,
}
img.onload = function () {
ctx1.drawImage(img, 0, 0)
ctx1.fillStyle = 'red'
ctx1.fillRect(p.x, p.y, 10, 10)
const degrees = 60
const radians = (Math.PI / 180) * degrees
ctx2.translate(viewport.width/2, viewport.height/2)
ctx2.rotate(radians)
const imgX = -p.x
const imgY = -p.y
ctx2.drawImage(scene, imgX, imgY)
}
}
(@ Kaiido同时给了我一个很好的解决方案。他的解决方案还考虑了调整以获得地图上红点的确切中心,这是我还没有做的事情。)