[HTML5] Canvas Rotiert nicht um den mittelpunk
lima-city → Forum → Die eigene Homepage → HTML, CSS & Javascript
abfrage
angeln
bedingung
code
doppelpunkt
fangen
fehler
frage
gedanke
grad
kontext
mittelpunkt
normalfall
reihenfolge
rotation
statement
text
url
wert wert code
zuweisung
-
Hallo,
Ich habe heute ein kleines Script erstellt, welches verschiedenfarbige Quadrate erstellt. Nun wollte ich diese noch dazu bringen sich um den Mitelpunkt zu rotieren allerdings schaffe ich das nicht so ganz.
Mein Code:
http://pastebin.com/XeJ5xhni
Kann mir einer sagen was mein Fehler ist? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Sry, dass ich das Thema erst jetzt sehe, dir Vorstellungsthreads drücken ein bisschen..
Also, generell solltest du dir mal gedanken über den Kontext machen. Es gibt in deinem Werk mehrere Fehler, fangen wir also an:
var c = document.getElementById("lol"); var ctx = c.getContext('2d'); ctx.translate(c.width / 2, c.height / 2); $("#cmd").text(width + ":" + height); $("#lol").attr("width", width); $("#lol").attr("height", height); angel += 1; ctx.rotate(Math.PI/angel);
Das wird erstmal in der Reihenfolge nicht gehen. Du resized das Canvas, nachdem du den Mittelpunkt verschoben hast. Das bewirkt, dass die Verschiebung rückgängig gemacht wird. Deine Reihenfolge muss mindestens so aussehen:
$("#cmd").text(width + ":" + height); $("#lol").attr("width", width); $("#lol").attr("height", height); var c = document.getElementById("lol"); var ctx = c.getContext('2d'); ctx.translate(c.width / 2, c.height / 2); angel += 1; ctx.rotate(Math.PI/angel);
Man könnt es auch nach dem "c.getContext" machen, aber das ist unschöner Stil. ERST alle HTML Veränderungen, DANN die Canvas Änderungen.
Jetzt wird dir auffallen, sind deine vermutlich in der unteren Ecke raus. Das liegt daran, dass du nun vom neuen Mittelpunkt aus zeichnest. Füge also eine rücktranslation des Mittelpunktes ein:
var c = document.getElementById("lol"); var ctx = c.getContext('2d'); ctx.translate(c.width / 2, c.height / 2); angel += 1; ctx.rotate(Math.PI/angel); ctx.translate(-c.width / 2, -c.height / 2);
Nun sind die Quadrate wieder richtig positioniert. Die Rotation ist aber noch sehr "kaputt". Eine Rotation sollte um Grad geschehen, damit du leichter damit arbeiten kannst. Daher rechne den Radianten in Grad um:
var c = document.getElementById("lol"); var ctx = c.getContext('2d'); ctx.translate(c.width / 2, c.height / 2); angel = (angel>=360) ? 0 : angel+1; // <<< änderung: um nicht über 360° zu kommen ctx.rotate(Math.PI/360 * angel); // <<< änderung um den Winkel in Grad zu haben ctx.translate(-c.width / 2, -c.height / 2);
Nun hast du aber ein Problem, welches schnell sichtbar wird: Du drehst die Ebene erst um 1°, dann um 2°, dann um 3°, in der Summe ist sie bereits um 6° gedreht. Entweder du drehst immer nur im 1°, dann wäre das dufte, oder du machst es richtig, indem du den Context bufferst:
var c = document.getElementById("lol"); var ctx = c.getContext('2d'); ctx.save(); // <<< änderung: speichere den context ctx.translate(c.width / 2, c.height / 2); angel = (angel>=360) ? 0 : angel+1; ctx.rotate(Math.PI/360 * angel); ctx.translate(-c.width / 2, -c.height / 2);
ctx.restore(); // <<< änderung: baue den Kontext wieder zurück setTimeout("_start()", speed);
Nun gibt es an sich nurnoch eine Sache zu tun: Der Kontext sollte jedesmal, wenn du neu zeichnen möchtest, aufgeräumt werden. Ansonsten sammelt sich der Buffer und wird immer größer, was manchmal irgendwie nicht schön ist. Daher solltest du schreiben:
var c = document.getElementById("lol"); var ctx = c.getContext('2d'); ctx.clearRect(0,0,width,height);
Das alles sind so ein paar Anstöße in Richtung, dass es so funktioniert, wie du es brauchst. Ich hoffe es hilft dir. Bei Fragen einfach fragen.
Liebe Grüße -
Einen riesen dank an dich für einen so gut und ausführlichen Post. Soweit habe ich alles verstanden wie du es meinst. Allerdings verstehe ich eine Zeile nicht so ganz:
angel = (angel>=360) ? 0 : angel+1;
Was bewirkt der Code? -
angel = (angel>=360) ? 0 : angel+1;
Ist eine gekürzte If-Abfrage. Ihre langform ist:
if (angel>=360) { angel = 0; } else angel = angel+1; }
angel wird also der Wert zugewiesen, der die If Bedingung ergibt. Mit(STATEMENT) ?
hast du ein equivalent zuif (STATEMENT) {
Dannach kommt einWert : Wert ;
Dies sind 2 Werte durch ein Doppelpunkt : getrennt. Der erste wird angenommen und angel zugewiesen, wenn die Bedingung, das STATEMENT, true ergibt. Der Wert hinter dem Doppelpunkt wird angenommen, wenn das STATEMENT false ergibt.
Diese gekürzten If-Statements sind besonders für Zuweisungen recht hilfreich, da sie den Code kürzen, aber im normalfall trotzdem gut verständlich sind.
Liebe Grüße -
ggamee schrieb:
angel = (angel>=360) ? 0 : angel+1;
Ist eine gekürzte If-Abfrage. Ihre langform ist:
if (angel>=360) { angel = 0; } else angel = angel+1; }
angel wird also der Wert zugewiesen, der die If Bedingung ergibt. Mit(STATEMENT) ?
hast du ein equivalent zuif (STATEMENT) {
Dannach kommt einWert : Wert ;
Dies sind 2 Werte durch ein Doppelpunkt : getrennt. Der erste wird angenommen und angel zugewiesen, wenn die Bedingung, das STATEMENT, true ergibt. Der Wert hinter dem Doppelpunkt wird angenommen, wenn das STATEMENT false ergibt.
Diese gekürzten If-Statements sind besonders für Zuweisungen recht hilfreich, da sie den Code kürzen, aber im normalfall trotzdem gut verständlich sind.
Liebe Grüße
Gut zu wissen und nochmals Danke. Habe meinen Code jetzt fast fertig geändert. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage