我可以获取画布上下文的当前旋转角度吗?

时间:2017-04-11 12:40:58

标签: javascript canvas

我想知道是否有办法获得画布的旋转角度。而不是使用这样的变量跟踪它:

 var angle = 0; // keeps track of the current angle of the ctx
 ctx.rotate( Math.PI / 2 );
 angle+= Math.Pi / 2;
 ...
 ctx.rotate( Math.Pi / 7 );
 angle+= Math.Pi / 7; 

2 个答案:

答案 0 :(得分:0)

在现代浏览器中,您可以感谢ctx.currentTransform属性 但不幸的是,它仍然没有得到广泛的支持(实际上它只是在撰写本文时才使用chrome),所以你可能仍然希望在应用时记录你的变换,IIRC,有一些libs在线就可以做到这一点。 / p>

因此,对于chrome和未来的浏览器(在某些范围内,今天也是FF),您可以获得此转换矩阵,然后您必须获得ba值的反正切值[a, b, c, d , e, f]矩阵。

// returns the current rotation in radians, ranged [0, 2π]
function getRotation() {
  let t = getTransform(ctx);
  let rad = Math.atan2(t.b, t.a);
  if (rad < 0) { // angle is > Math.PI
    rad += Math.PI * 2;
  }
  return rad;
}

const ctx = document.createElement('canvas').getContext('2d');

function setAngle() {
  ctx.setTransform(1, 0, 0, 1, 0, 0); // reset the transform matrix
  let angle = Math.random() * Math.PI * 2;
  ctx.rotate(angle);
  console.log(angle, getRotation());
}

btn.onclick = setAngle;

// Try to support FF
// this is only a getter, and it doesn't implement the SVGMatrix's methods if not supported
function getTransform(ctx) {
  if ('currentTransform' in ctx) {
    return ctx.currentTransform
  }
  // restructure FF's array to an Matrix like object
  else if (ctx.mozCurrentTransform) {
    let a = ctx.mozCurrentTransform;
    return {a:a[0], b:a[1], c:a[2], d:a[3], e:a[4], f:a[5]};
  }
}
<button id="btn">set and get rotation</button>

您可能会注意到设定角度和获得的角度并不完全相同(至少在FF中),我会将其置于舍入问题的背后。

答案 1 :(得分:0)

您可以修改 prototypeCanvasRenderingContext2D 以支持这一点。

TypeScript 代码

这可确保编辑器为 context.rotation 属性显示正确的代码完成。

interface CanvasRenderingContext2D {
   rotation: number;
}

{
   const rotate = CanvasRenderingContext2D.prototype.rotate;
   Object.assign(CanvasRenderingContext2D.prototype, {
      rotate (angle: number) {
         rotate.call(this, angle);
         this.rotation += angle;
      },
      rotation: 0
   });
}

JavaScript 代码

如果您不知道 TypeScript 是什么,请使用它。

{
    const rotate = CanvasRenderingContext2D.prototype.rotate;
    Object.assign(CanvasRenderingContext2D.prototype, {
        rotate (angle) {
            rotate.call(this, angle);
            this.rotation += angle;
        },
        rotation: 0
    });
}

使用

执行上述代码后创建的任何上下文都将具有 rotation 属性。对于弧度,使用 context.rotation。对于学位,请使用 context.rotation * 180 / Math.PI