kostenloser Webspace werbefrei: lima-city


[HTML5] Canvas Rotiert nicht um den mittelpunk

lima-cityForumDie eigene HomepageHTML, CSS & Javascript

  1. Autor dieses Themas

    masterakio1995

    Kostenloser Webspace von masterakio1995

    masterakio1995 hat kostenlosen Webspace.

    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?
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. g****e

    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
  4. Autor dieses Themas

    masterakio1995

    Kostenloser Webspace von masterakio1995

    masterakio1995 hat kostenlosen Webspace.

    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?
  5. g****e

    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 zu
    if (STATEMENT) {
    Dannach kommt ein
    Wert : 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
  6. Autor dieses Themas

    masterakio1995

    Kostenloser Webspace von masterakio1995

    masterakio1995 hat kostenlosen Webspace.

    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 zu
    if (STATEMENT) {
    Dannach kommt ein
    Wert : 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.
  7. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!