web-dev-qa-db-ja.com

HTML 5キャンバスで単一のオブジェクトを回転させるにはどうすればよいですか?

私は、html 5キャンバスで単一のオブジェクトを回転させる方法を見つけようとしています。

例: http://screencast.com/t/NTQ5M2E3Mzct -これらのカードのそれぞれを異なる角度で回転させたい。

これまでのところ、私が見たのは、キャンバス全体を回転させる方法を示す記事と例だけです。今、私は、2番目の画像を描画する前に、キャンバスを回転させ、画像を描画し、キャンバスを元の位置に戻す必要があると推測しています。その場合は、お知らせください!別の方法があると感じています。

誰もが考えていますか?

前もって感謝します!

33
Kappers

残念ながら、HTML5キャンバス要素では、個々の要素を回転させることはできません。

アニメーションは、MSペイントでの描画のように機能します。何かを描き、画面を作成します。消しゴムを使用して、いくつかのものを削除したり、異なるものを描画したり、画面を作成します。

キャンバス上に既存のアイテムがある場合は、それを消去する必要があります(たとえば、ctx.fillRect()またはclearRect()を使用します)、回転したオブジェクトを描画します。

そもそも描画中に回転させる方法がわからない場合:

ctx.save();
ctx.rotate(0.17);
// draw your object
ctx.restore();
39
Artiom Chilaru

私は最近のプロジェクトで同じ問題に遭遇しました(そこで、私はあちこちで回転するエイリアンを蹴りました)。同じことを行うこの謙虚な関数を使用しました。ctx.rotateと同じ方法で使用できますが、角度を渡すことができます。私には問題ありません。

function drawImageRot(img,x,y,width,height,deg){
    // Store the current context state (i.e. rotation, translation etc..)
    ctx.save()

    //Convert degrees to radian 
    var rad = deg * Math.PI / 180;

    //Set the Origin to the center of the image
    ctx.translate(x + width / 2, y + height / 2);

    //Rotate the canvas around the Origin
    ctx.rotate(rad);

    //draw the image    
    ctx.drawImage(img,width / 2 * (-1),height / 2 * (-1),width,height);

    // Restore canvas state as saved from above
    ctx.restore();
}

ええ、私の最初の答え!

60
user1602942

個々のオブジェクトを回転させるには、変換マトリックスを設定する必要があります。これは本当に簡単です。

<body>
    <canvas width="1280" height="720" id="pageCanvas">
        You do not have a canvas enabled browser
    </canvas>
    <script>
        var context = document.getElementById('pageCanvas').getContext('2d');
        var angle = 0;
        function convertToRadians(degree) {
            return degree*(Math.PI/180);
        }

        function incrementAngle() {
            angle++;
            if(angle > 360) {
                angle = 0;
            }
        }

        function drawRandomlyColoredRectangle() {  
            // clear the drawing surface
            context.clearRect(0,0,1280,720);
            // you can also stroke a rect, the operations need to happen in order 
            incrementAngle();
            context.save();                
            context.lineWidth = 10;  
            context.translate(200,200);
            context.rotate(convertToRadians(angle));
            // set the fill style
            context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
            context.fillRect(-25,-25,50,50);
            context.strokeRect(-25,-25,50,50);                
            context.restore();
        }

        // Ideally use getAnimationFrame but for simplicity:
        setInterval(drawRandomlyColoredRectangle, 20);
    </script>
</body>
16
Anthony W

基本的に、他の形状を回転させずにオブジェクトを適切に回転させるには、以下を行う必要があります。

  1. コンテキストを保存します:ctx.save()
  2. ピボットポイントを目的の場所に移動します:ctx.translate(200、200);
  3. 回転:context.rotate(45 * Math.PI/180);
  4. 形状、スプライト、何でも描く:ctx.draw ...
  5. ピボットをリセットします:ctx.translate(-200、-200);
  6. コンテキストを元の状態に復元します:ctx.restore();
function spinDrawing() {
    ctx.save();
    ctx.translate(200, 200);
    context.rotate(45 * Math.PI / 180);
    ctx.draw //your drawing function
    ctx.translate(-200, -200);
    ctx.restore();
}

警告:翻訳後、キャンバスの原点が変更されました。つまり、シェイプを描画するときに、シェイプの座標がそれに合わせて調整されます。

上記のリストの外側に描かれた形状は影響を受けません。役に立てば幸いです。

8
TTalt

このhtml/javascriptコードは、問題を明らかにする可能性があります。

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="233" height="233" style="border:1px solid #d3d3d3;">
your browser does not support the canvas tag </canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var canvasWidth=233;
var canvasHeight=233;
var rectWidth=100;
var rectHeight=150;
var x=30;
var y=30;
var translateX= x+(rectWidth/2);
var translateY= y+(rectHeight/2);

ctx.fillRect(x,y,rectWidth,rectHeight);

ctx.translate(translateX,translateY);
ctx.rotate(5*Math.PI/64); /* just a random rotate number */
ctx.translate(-translateX,-translateY); 
ctx.fillRect(x,y,rectWidth,rectHeight);


</script>

</body>
</html>

回転に関連する数学を見ることは有益だと思います。これもあなたにも役立つと思います。

3
turbopipp
<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="500" height="450" style="border:1px solid #d3d3d3;">
</canvas>

<Button id = "right" onclick = "rotateRight()">Right</option>
<Button id = "left" onclick = "rotateLeft()">Left</option>
<script src = "zoom.js">

</script>

<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

createRect();

function rotateRight()
{
 ctx.save();
 ctx.clearRect(0,0,500,450);
 ctx.translate(c.width/2,c.height/2);
 ctx.rotate(10*Math.PI/180 );  
 ctx.translate(-c.width/2,-c.height/2);
 createRect();

}

function rotateLeft()
{
 ctx.save();
 ctx.clearRect(0,0,500,450);
 ctx.translate(c.width/2,c.height/2);
 ctx.rotate(-10*Math.PI/180 );  
 ctx.translate(-c.width/2,-c.height/2);
 createRect();  
}



function createRect()
{
 ctx.beginPath();
 ctx.fillStyle = "#AAAA00";
 ctx.fillRect(250,250,90,50);
}
</script>

</body>
</html>
2
PGB

オブジェクトを回転させるために使用できます rotate() 方法。ここでは、長方形のオブジェクトを時計回りに135度回転させる方法の例を示します。

 <script>
  var canvas = document.getElementById('Canvas01');
  var ctx = canvas.getContext('2d');

  var rectWidth = 100;
  var rectHeight = 50;

  //create line
  ctx.strokeStyle= '#ccc';
  ctx.beginPath();
  ctx.moveTo(canvas.width / 2, 0);
  ctx.lineTo(canvas.width / 2, canvas.height);
  ctx.stroke();
  ctx.closePath();

  ctx.beginPath();
  ctx.moveTo(0, canvas.height/2);
  ctx.lineTo(canvas.width, canvas.height/2);
  ctx.stroke();
  ctx.closePath();

  // translate ctx to center of canvas
  ctx.translate(canvas.width / 2, canvas.height / 2);

  // rotate the rect to 135 degrees of clockwise
  ctx.rotate((Math.PI / 180)*135);

  ctx.fillStyle = 'blue';
  ctx.fillRect(0, 0, rectWidth, rectHeight);
</script>
</body>

ここでデモとあなたは自分で試すことができます: http://okeschool.com/examples/canvas/html5-canvas-rotate

2
MichaelCalvin

この質問を見つけたのは、キャンバスにたくさんの物があり、キャンバスの線で苦労して描いた後、それらのいくつかを回転させることを決めたからです。たくさんの複雑なことを二度とやりたくないので、自分が持っているものを回転させたいと思いました。私が見つけた簡単な解決策はこれでした:

ctx.save();

ctx.translate(x+width_of_item/2,y+height_of_item/2);
ctx.rotate(degrees*(Math.PI/180));
ctx.translate(-(x+width_of_item/2),-(y+height_of_item/2));

// THIS IS THE STUFF YOU WANT ROTATED
// do whatever it is you need to do here, moveto and lineto is all i used 
// I would expect anything to work. use normal grid coordinates as if its a
// normal 0,0 in the top left kind of grid

ctx.stroke();
ctx.restore();

とにかく-それは特にエレガントではないかもしれませんが、特定の要素をキャンバスに回転させる非常に簡単な方法です。

すべての回転した要素を見てください!

0