我想知道是否有办法获得画布的旋转角度。而不是使用这样的变量跟踪它:
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;
答案 0 :(得分:0)
在现代浏览器中,您可以感谢ctx.currentTransform
属性
但不幸的是,它仍然没有得到广泛的支持(实际上它只是在撰写本文时才使用chrome),所以你可能仍然希望在应用时记录你的变换,IIRC,有一些libs在线就可以做到这一点。 / p>
因此,对于chrome和未来的浏览器(在某些范围内,今天也是FF),您可以获得此转换矩阵,然后您必须获得b
和a
值的反正切值[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)
您可以修改 prototype
的 CanvasRenderingContext2D
以支持这一点。
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
。