Canvas HTML画布:旋转和转换图像,将图像中的点固定到画布中的坐标

Canvas HTML画布:旋转和转换图像,将图像中的点固定到画布中的坐标,canvas,Canvas,代码笔在这里: 问题:给定在一个画布上渲染的场景,在对画布1的图像/场景应用旋转后,我需要应用哪些变换以使第一个画布上的点(已知x1,y1)位于第二个画布上的某个固定点(已知x2,y2,但相对于第二个画布,而不是相对于第一个画布) 请参见上面的代码笔,以了解要使用的操场。试着让红点在视口中居中。操作旋转(度变量)和 P.x/Cuff>和 Py y 为任意值,并测试您的转换代码是否仍然有效(保持红色点在视口的中间)。< /P> 我尝试了很多应用sin、cos、逆sin、逆cos和勾股定理的方法,但

代码笔在这里:

问题:给定在一个画布上渲染的场景,在对画布1的图像/场景应用旋转后,我需要应用哪些变换以使第一个画布上的点(已知x1,y1)位于第二个画布上的某个固定点(已知x2,y2,但相对于第二个画布,而不是相对于第一个画布)

请参见上面的代码笔,以了解要使用的操场。试着让红点在视口中居中。操作旋转(<代码>度<代码>变量)和<代码> P.x/Cuff>和<代码> Py y <代码>为任意值,并测试您的转换代码是否仍然有效(保持红色点在视口的中间)。< /P>
我尝试了很多应用sin、cos、逆sin、逆cos和勾股定理的方法,但都没有成功。

您需要的是定义将在
drawImage
中使用的源坐标

这些坐标是点坐标的负值+目标画布大小的一半,因此,无论点位于源画布的何处,都会在目标画布的中心绘制该点

一旦你有了它,你所要做的就是应用基本的

translate(center, center);
rotate(angle);
drawImage(img, -center, -center);
函数绘图(){
const scene=document.getElementById('canvas-scene')
const ctx1=scene.getContext('2d')
const viewport=document.getElementById('canvas-viewport')
const ctx2=viewport.getContext('2d')
常数p={
x:(Math.random()*(ctx1.canvas.width-20))+10,
y:(Math.random()*(ctx1.canvas.height-20))+10,
};
常数弧度=(Math.PI*2*Math.random());
设img=新图像();
img.src=http://www.mngeo.state.mn.us/chouse/images/sibley_shillinglake_nc.jpg'
img.onload=函数(){
ctx1.drawImage(img,0,0)
ctx1.fillStyle='red'
ctx1.fillRect(p.x-5,p.y-5,10,10);
//获取目标宽度和高度
常数cw=ctx2.canvas.width,
ch=ctx2.canvas.height,
//新坐标是点坐标的负数+新画布宽度的一半
newX=(p.x*-1)+cw/2,
newY=(p.y*-1)+ch/2;
//移到画布中心
ctx2.翻译(cw/2,ch/2);
ctx2.旋转(弧度);
//通过平移回左上角进行绘制
ctx2.drawImage(场景,newX-cw/2,newY-ch/2);
}
}
draw()
#画布视口{
边框:1px纯黑;
边缘底部:40px;
}
视口
场景
我让它工作了:

结果证明根本不需要三角函数

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)
  }
}

(@kaido同时给了我一个很好的解决方案。他的解决方案还考虑了调整以获得地图上红点的准确中心,这是我还没有费心去做的。)

我独立于你得出了一个可行的解决方案,但我看到你的解决方案可行,所以我会给你一个向上投票和接受的结果。