Холст вращается от нижнего центра угла изображения?

Как повернуть изображение с помощью элемента canvas html5 из нижнего центрального угла?

<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>

К сожалению это, кажется, поворачивает это от верхнего левого угла изображения. Есть идеи?

Редактировать: в конце объект (космический корабль) должен вращаться как указатель часов, как будто он поворачивает вправо / влево.

13.12.2008 16:21:00
code.google.com/p/explorercanvas Это добавит вам отличную поддержку кроссбраузерности, это не одно и то же, поскольку для IE вы фактически будете использовать VML
user525321 30.11.2010 14:56:20
4 ОТВЕТА
РЕШЕНИЕ

Сначала вы должны перевести в точку, вокруг которой вы хотели бы вращаться. В этом случае размеры изображения составляют 64 x 120. Чтобы повернуть вокруг нижнего центра, вы хотите перевести на 32, 120.

ctx.translate(32, 120);

Это подводит вас к нижнему центру изображения. Затем поверните холст:

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

Которые поворачиваются на 90 градусов.

Затем, когда вы рисуете изображение, попробуйте это:

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

? Это работает?

27
13.12.2008 16:51:04
Действительно удивительно: еще раз спасибо. Я думаю, что я понимаю это сейчас.
Tom 13.12.2008 17:38:13
Обновление: есть проблема, хотя левая сторона обрезается из-за ширины, я думаю. Есть какой-нибудь способ исправить это, но все же под этим большим углом?
Tom 13.12.2008 17:47:05
Похоже, я исправил это, установив ctx.translate (232, 120); - установка вашего ответа в качестве принятого ответа :)
Tom 13.12.2008 18:03:09
@Vincent пожалуйста , вы можете посмотреть в stackoverflow.com/questions/17487277/... . спасибо :)
Beginner 5.07.2013 15:04:50

Правильный ответ, конечно же, Винсента.
Я немного возился с этим вращением / переводом, и я думаю, что мои маленькие эксперименты могут быть интересны, чтобы показать:

<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>

Моим камнем преткновения было то, что позиционировать повернутую фигуру сложно, потому что она расположена вдоль повернутой оси: либо нам нужно выполнить некоторую тригонометрию, чтобы нарисовать примитивный источник, либо мы должны нарисовать на вторичном скрытом холсте и затем нарисовать его на целевой.
Разве у кого-то есть идея получше?

3
14.12.2008 10:01:19
<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>
-1
1.06.2010 12:29:56

Я использовал это, когда мне нужно было вращать тексты, начиная с указанной точки (центра)?

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();
1
4.04.2013 18:40:38