Es gibt keine Möglichkeit, jetzt auszuführen, um die aktuelle Transformationsmatrix zu erhalten, so würden Sie Spur von irgendwelchen Drehungen/Übersetzungen halten müssen/sich selbst skalieren.
Um die Transformation tatsächlich durchzuführen, müssen Sie die Transformationsmatrix mit dem Punkt multiplizieren (als Spaltenvektor).
Sie können die Methoden, die die Transformation beeinflussen, überschreiben, um Ihre eigene Kopie der Matrix zu speichern. Ich habe diesen Code nicht getestet, aber so etwas wie dies funktionieren sollte:
var contextPrototype = CanvasRenderingContext2D.prototype;
contextPrototype.xform = Matrix.I(3);
contextPrototype.realSave = contextPrototype.save;
contextPrototype.save = function() {
if (!this.xformStack) {
this.xformStack = [];
}
this.xformStack.push(this.xform.dup());
this.realSave();
}
contextPrototype.realRestore = contextPrototype.restore;
contextPrototype.restore = function() {
if (this.xformStack && this.xformStack.length > 0) {
this.xform = this.xformStack.pop();
}
this.realRestore();
}
contextPrototype.realScale = contextPrototype.scale;
contextPrototype.scale = function(x, y) {
this.xform = this.xform.multiply($M([
[x, 0, 0],
[0, y, 0],
[0, 0, 1]
]));
this.realScale(x, y);
}
contextPrototype.realRotate = contextPrototype.rotate;
contextPrototype.rotate = function(angle) {
var sin = Math.sin(angle);
var cos = Math.cos(angle);
this.xform = this.xform.multiply($M([
[cos, -sin, 0],
[sin, cos, 0],
[ 0, 0, 1]
]));
this.realRotate(angle);
}
contextPrototype.realTranslate = contextPrototype.translate;
contextPrototype.translate = function(x, y) {
this.xform = this.xform.multiply($M([
[1, 0, x],
[0, 1, y],
[0, 0, 1]
]));
this.realTranslate(x, y);
}
contextPrototype.realTransform = contextPrototype.transform;
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
this.xform = this.xform.multiply($M([
[m11, m21, dx],
[m12, m22, dy],
[ 0, 0, 1]
]));
this.realTransform(m11, m12, m21, m22, dx, dy);
}
contextPrototype.realSetTransform = contextPrototype.setTransform;
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
this.xform = $M([
[m11, m21, dx],
[m12, m22, dy],
[ 0, 0, 1]
]);
this.realSetTransform(m11, m12, m21, m22, dx, dy);
}
Ich benutzte die Sylvester matrix library für Bequemlichkeit, aber Sie können Ihre eigene Vermehrung zu tun.
den transformierten Punkt zu erhalten, multiplizieren Sie einfach die Transformations-Matrix durch den Punkt:
// Get the transformed point as [x, y]
contextPrototype.getTransformedPoint = function(x, y) {
var point = this.xform.multiply($V([x, y, 1]));
return [point.e(1), point.e(2)];
}
Dies muss save() und restore() als auch implementieren, aber es sieht genau richtig und sollte das Häkchen bekommen . –
Guter Punkt über save() und restore(). Ich werde diese hinzufügen. –
Das funktionierte auf Anhieb ... perfekt, danke !! Aber warum sie im Original nicht daran gedacht hätten, ist mir ein Rätsel. : / – HostileFork