tne*_*niv 27 javascript html5 canvas
有没有办法获得画布的当前变换矩阵?有一个context.setTransform()函数,但据我所知,似乎没有getTransform()等价.
更具体地说,我想获得矩阵的当前比例和平移元素.谷歌一直对此毫无帮助.
Sim*_*ris 30
不,根本就没有.:(
大多数canavs库(例如cake.js)已经实现了自己的矩阵类来跟踪当前的转换矩阵.
cake.js的创建者认为没有办法获得当前的矩阵是荒谬的,足以保证有关它的错误报告.不幸的是,这是在2007年,并且没有努力在规范中包含getCurrentTransform.
编辑:我创建了一个简单的Transformation类,它允许您轻松地自己创建getCanvas()或跟踪Canvas的矩阵并排.这里是.我希望有所帮助!
编辑2012年6月:新规范确实包含了获取当前转换矩阵的方法!context.currentTransform可用于获取或设置当前变换矩阵.遗憾的是,虽然Firefox确实mozCurrentTransform在其上下文中具有特定于供应商的属性,但尚未实现它.所以你还不能使用它,但很快就会出现在规范中!
ell*_*ben 12
EDIT(2016年6月27日):WHATWG规范现在有一个函数getTransform()而不是currentTransform它,它在语义上看起来很清晰,它getTransform()创建了一个转换矩阵的副本.看起来主流浏览器仍然缺少它.
编辑,再次:
这是一个粗略的实现:
//in theory, SVGMatrix will be used by the Canvas API in the future;
//in practice, we can borrow an SVG matrix today!
var createMatrix = function() {
var svgNamespace = "http://www.w3.org/2000/svg";
return document.createElementNS(svgNamespace, "g").getCTM();
}
//`enhanceContext` takes a 2d canvas context and wraps its matrix-changing
//functions so that `context._matrix` should always correspond to its
//current transformation matrix.
//Call `enhanceContext` on a freshly-fetched 2d canvas context for best
//results.
var enhanceContext = function(context) {
var m = createMatrix();
context._matrix = m;
//the stack of saved matrices
context._savedMatrices = [m];
var super_ = context.__proto__;
context.__proto__ = ({
//helper for manually forcing the canvas transformation matrix to
//match the stored matrix.
_setMatrix: function() {
var m = this._matrix;
super_.setTransform.call(this, m.a, m.b, m.c, m.d, m.e, m.f);
},
save: function() {
this._savedMatrices.push(this._matrix);
super_.save.call(this);
},
//if the stack of matrices we're managing doesn't have a saved matrix,
//we won't even call the context's original `restore` method.
restore: function() {
if(this._savedMatrices.length == 0)
return;
super_.restore.call(this);
this._matrix = this._savedMatrices.pop();
this._setMatrix();
},
scale: function(x, y) {
this._matrix = this._matrix.scaleNonUniform(x, y);
super_.scale.call(this, x, y);
},
rotate: function(theta) {
//canvas `rotate` uses radians, SVGMatrix uses degrees.
this._matrix = this._matrix.rotate(theta * 180 / Math.PI);
super_.rotate.call(this, theta);
},
translate: function(x, y) {
this._matrix = this._matrix.translate(x, y);
super_.translate.call(this, x, y);
},
transform: function(a, b, c, d, e, f) {
var rhs = createMatrix();
//2x2 scale-skew matrix
rhs.a = a; rhs.b = b;
rhs.c = c; rhs.d = d;
//translation vector
rhs.e = e; rhs.f = f;
this._matrix = this._matrix.multiply(rhs);
super_.transform.call(this, a, b, c, d, e, f);
},
//warning: `resetTransform` is not implemented in at least some browsers
//and this is _not_ a shim.
resetTransform: function() {
this._matrix = createMatrix();
super_.resetTransform.call(this);
},
__proto__: super_
});
return context;
};
Run Code Online (Sandbox Code Playgroud)
编辑:该属性currentTransform 已添加到规范 ; 据报道,Firefox和Opera支持它.我检查了Firefox并发现它以供应商为前缀mozCurrentTransform.据推测,它可用于获取和设置变换矩阵.
老笨蛋,仍然是最好的:
如果您想获得当前的转换矩阵,您必须自己跟踪它.这样做的一种方法是使用Javascript的原型继承来添加getMatrix()方法并扩充修改矩阵的方法:
var context = canvas.getContext("2d");
var super = context.__proto__;
context.__proto__ = ({
__proto__: super, //"inherit" default behavior
getMatrix: function() { return this.matrix; },
scale: function(x, y) {
//assuming the matrix manipulations are already defined...
var newMatrix = scaleMatrix(x, y, this.getMatrix());
this.matrix = newMatrix;
return super.scale.call(this, x, y);
},
/* similar things for rotate, translate, transform, setTransform */
/* ... */
});
context.matrix = makeDefaultMatrix();
Run Code Online (Sandbox Code Playgroud)
要真正做到正确,您需要在使用上下文save()和restore()方法时跟踪多个矩阵.
| 归档时间: |
|
| 查看次数: |
18834 次 |
| 最近记录: |