2008-12-13 18 views
15

W jaki sposób obrócić obraz z elementem canvas html5 od dolnego kąta środkowego?Obrót płótna od dolnego środkowego kąta obrazu?

<html> 
    <head> 
     <title>test</title> 
     <script type="text/javascript"> 
      function startup() { 
       var canvas = document.getElementById('canvas'); 
       var ctx = canvas.getContext('2d'); 
       var img = new Image(); 
       img.src = 'player.gif'; 
       img.onload = function() { 
        ctx.translate(185, 185); 
        ctx.rotate(90 * Math.PI/180); 
        ctx.drawImage(img, 0, 0, 64, 120); 
       } 
      } 
     </script> 
    </head> 
    <body onload='startup();'> 
     <canvas id="canvas" style="position: absolute; left: 300px; top: 300px;" width="800" height="800"></canvas> 
    </body> 
</html> 

Niestety wydaje się, że obraca to od lewego górnego kąta obrazu. Dowolny pomysł?

Edycja: na koniec obiekt (statek kosmiczny) musi się obracać jak wskaźnik zegarowy, tak jakby obracał się w prawo/lewo.

+0

http://code.google.com/p/explorercanvas/ To doda ci wielkie wsparcie dla wielu przeglądarek, to nie jest to samo, ponieważ dla IE będzie faktycznie używać VML –

+0

Zobacz również [Korzystanie z HTML5 Canvas obrócić obraz o Arbitrary Point] (http://stackoverflow.com/questions/4649836/using-html5-canvas-rotate-image-about-arbitrary-point) – Phrogz

Odpowiedz

26

Najpierw musisz przetłumaczyć do punktu, w którym chcesz obrócić. W tym przypadku wymiary obrazu to 64 x 120. Aby obrócić wokół dolnej środkowej chcesz tłumaczyć do 32, 120.

ctx.translate(32, 120); 

To prowadzi do dolnej środkowej części obrazu. Następnie obróć płótno:

ctx.rotate(90 * Math.PI/180); 

Które obracają się o 90 stopni.

Wtedy, kiedy narysować obraz spróbuj tego:

ctx.drawImage(img, -32, -120, 64, 120); 

? Czy to działa?

+0

Naprawdę niesamowite: jeszcze raz dziękuję. Myślę, że rozumiem teraz. – Tom

+0

Aktualizacja: jest jednak problem, lewa strona jest odcinana z powodu mojej szerokości. Jakikolwiek sposób to naprawić, ale wciąż masz ten świetny kąt? – Tom

+0

Wygląda na to, że naprawiłem go, ustawiając ctx.translate (232, 120); - ustawiając twoją odpowiedź jako zaakceptowaną odpowiedź :) – Tom

3

Prawidłowa odpowiedź to oczywiście odpowiedź Vincenta.
I grzebał trochę z tej rotacji/translacji rzeczy i myślę, że moje małe eksperymenty mogą być interesujące, aby pokazać:

<html> 
    <head> 
    <title>test</title> 
    <script type="text/javascript"> 
    canvasW = canvasH = 800; 
    imgW = imgH = 128; 
    function startup() { 
     var canvas = document.getElementById('canvas'); 
     var ctx = canvas.getContext('2d'); 
     // Just to see what I do... 
     ctx.strokeRect(0, 0, canvasW, canvasH); 
     var img = new Image(); 
     img.src = 'player.png'; 
     img.onload = function() { 
     // Just for reference 
     ctx.drawImage(img, 0, 0, 128, 128); 
     ctx.drawImage(img, canvasW/2 - imgW/2, canvasH/2 - imgH/2, 128, 128); 
     mark(ctx, "red"); 
     // Keep current context (transformations) 
     ctx.save(); 
     // Put bottom center at origin 
     ctx.translate(imgW/2, imgH); 
     // Rotate 
     // Beware the next translations/positions are done along the rotated axis 
     ctx.rotate(45 * Math.PI/180); 
     // Mark new origin 
     mark(ctx, "red"); 
     // Restore position 
     ctx.translate(-imgW/2, -imgH); 
     ctx.drawImage(img, 0, 0, imgW, imgH); 
     mark(ctx, "green"); 
     // Draw it an wanted position 
     ctx.drawImage(img, canvasW/2, canvasH/3, imgW, imgH); 
     // Move elsewhere: 
     ctx.translate(canvasW/2, canvasH/2); 
     ctx.drawImage(img, 0, 0, imgW, imgH); 
     mark(ctx, "blue"); 
     ctx.restore(); 
     } 
    } 
    function mark(ctx, color) { 
    ctx.save(); 
//~  ctx.fillStyle = color; 
//~  ctx.fillRect(-2, -2, 4, 4); 
    ctx.strokeStyle = color; 
    ctx.strokeRect(0, 0, imgW, imgH); 
    ctx.restore(); 
    } 
    </script> 
    </head> 
    <body onload='startup();'> 
    <canvas id="canvas" style="position: absolute; left: 300px; top: 300px;" width="800" height="800"></canvas> 
    </body> 
</html> 

Moja potykając problemem było to, że pozycjonowanie obróconego postać jest trudne, ponieważ jest wzdłuż obróconych oś: albo musimy trochę matematyki trigo do malowania w pierwotnym pochodzenie, albo musimy narysować na wtórnym ukrytym płótnie, a następnie pomalować go na docelowy.
Chyba, że ​​ktoś inny ma lepszy pomysł?

-1
<html> 
    <head> 
    <title>Canvas Pinball flippers by stirfry</title> 
    <script type="application/x-javascript"> 
    /*THIS SCRIPT ADAPTED BY STIRFRY. SOURCE TEETHGRINDER no warranty or liability implied or otherwise. use at your own risk. No credit required. Enjoy.stirfry.thank(you)*/ 
    var img = new Image(); 
          //img.src = "flipper.gif";//right 
    img.src="http://i39.tinypic.com/k1vq0x.gif" 
    var img2 = new Image(); 
          //img2.src = "flipper2.gif";//left 
    img2.src ="http://i42.tinypic.com/14c8wht.gif" 
    var gAngle = 0; 
    gAngle = 60; 
    stop = false; 
    inertia = .8; 
    vel = 10; 
    k = 0.1; 

    function drawagain(){ 
     gAngle = 60; 
     stop = false; 
     inertia = .8; 
     vel = 10; 
     k = 0.1; 
    draw() 
    } 

    function draw(){ 
    var ctx = document.getElementById('canvas').getContext('2d'); 
    ctx.save(); 

     vel = (vel * inertia) + (-gAngle * k); 

     gAngle += vel; 

     ctx.fillStyle = 'rgb(255,255,255)'; 
     ctx.fillRect (0, 0, 600, 600); 

     ctx.translate(380, 480);    //location of the system 
     ctx.rotate(gAngle * Math.PI/180);//rotate first then draw the flipper 
     ctx.drawImage(img, -105, -16); 
ctx.restore(); 
ctx.save(); 
     ctx.translate(120, 480);    //location of the system 
     ctx.rotate(-1*gAngle * Math.PI/180);//rotate first then draw the flipper 
     ctx.drawImage(img2, -18, -16); 

ctx.restore(); 

     if(!stop) 
      setTimeout(draw, 30); 
     } 

    </script> 
    <style type="text/css"> 
     body { margin: 20px; font-family: arial,verdana,helvetica; background: #fff;} 
     h1 { font-size: 140%; font-weight:normal; color: #036; border-bottom: 1px solid #ccc; } 
     canvas { border: 2px solid #000; float: left; margin-right: 20px; margin-bottom: 20px; } 
     pre { float:left; display:block; background: rgb(238,238,238); border: 1px dashed #666; padding: 15px 20px; margin: 0 0 10px 0; } 
     .gameLayer {position: absolute; top: 0px; left: 0px;} 
     #scoreLayer {font-family: arial; color: #FF0000; left: 10px; font-size: 70%; } 
     #windowcontainer {position:relative; height:300px;} 
    </style> 
    </head> 

    <body onload="draw()"> 
    <div id="windowcontainer"> 
     <canvas id="canvas" width="500" height="500"></canvas> 
     <INPUT VALUE="flip" TYPE=BUTTON onClick="drawagain();"><br/> 
    </div> 

    </body> 
</html> 
+0

Twój przykład zawiera błędy. –

0

Użyłem tego, kiedy potrzebowałem obracać teksty rozpoczęte od ich określonego punktu (centrum)?

ctx.save(); 
ctx.translate(x,y); 
ctx.rotate(degree*Math.PI/180); 
ctx.translate(-x,-y); 
ctx.fillText(text,x,y); 
ctx.stroke(); 
ctx.restore();