代码之家  ›  专栏  ›  技术社区  ›  Your Common Sense

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

  •  0
  • Your Common Sense  · 技术社区  · 7 年前

    代码在此打开: https://codepen.io/anon/pen/XEYEKd

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

    请参见上面的代码笔,以了解要使用的操场。试着让红点在视口中居中。操纵旋转( degrees 变量)和 p.x p.y 设置为任意值,并测试转换代码是否仍然有效(以保持视口中间的红点)。

    我尝试了很多应用sin,cos,逆sin,逆cos和毕达哥拉斯定理的方法,但都没有成功。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Kaiido NickSlash    7 年前

    您需要定义将在中使用的源坐标 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>
        2
  •  0
  •   Your Common Sense    7 年前

    我成功了: 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)
      }
    }
    

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