如何在html 5画布上旋转单个对象?

问题描述 投票:33回答:8

我试图弄清楚如何在html 5画布上旋转单个对象。

例如:http://screencast.com/t/NTQ5M2E3Mzct - 我希望这些卡中的每一张都以不同的程度旋转。

到目前为止,我所看到的只是文章和示例,演示了旋转整个画布的方法。现在,我猜我必须旋转画布,绘制图像,然后在绘制第二个图像之前将画布旋转回原始位置。如果是这样的话,请告诉我!我只是觉得还有另一种方式。

任何人都有任何想法?

提前致谢!

javascript animation html5 canvas
8个回答
39
投票

不幸的是,在HTML5 canvas元素中,您无法旋转单个元素。

动画的工作方式就像在MS画中绘画一样:你绘制一些东西,制作一个屏幕..使用橡皮擦去除一些东西,绘制不同的东西,制作一个屏幕..在顶部绘制其他东西,制作一个屏幕......等等。

如果画布上有现有项目 - 您必须将其擦除(例如使用ctx.fillRect()clearRect()),然后绘制旋转的对象。

如果您在第一时间绘图时不确定如何旋转它:

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

60
投票

我在最近的一个项目中遇到了同样的问题(我在那里踢了外星人)。我只是使用了这个简单的函数来做同样的事情,并且可以像ctx.rotate一样使用,但可以传递一个角度。对我来说很好。

function drawImageRot(img,x,y,width,height,deg){

    //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);

    //reset the canvas  
    ctx.rotate(rad * ( -1 ) );
    ctx.translate((x + width / 2) * (-1), (y + height / 2) * (-1));
}

是的,我的第一个答案!


16
投票

要旋转单个对象,您必须设置变换矩阵。这很简单:

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

8
投票

基本上,要使对象正确旋转而不使其他形状旋转,您需要:

  1. 保存上下文:ctx.save()
  2. 将枢轴点移动到所需位置:ctx.translate(200,200);
  3. rotate:context.rotate(45 * Math.PI / 180);
  4. 绘制形状,精灵,无论如何:ctx.draw ...
  5. 重置pivot: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();
}

注意事项:翻译后,画布的原点发生了变化,这意味着在绘制形状时,应相应地对齐形状的坐标。

在上述列表之外绘制的形状不会受到影响。我希望它有所帮助。


3
投票

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

我发现看到与旋转有关的数学很有帮助,我希望这也对你有帮助。


2
投票
<!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
投票

要旋转对象,可以使用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


0
投票

我发现了这个问题,因为我在画布上画了一堆东西,用画布线画出来,苦心经营,然后决定其中一些应该旋转。不想再做一大堆复杂的东西我想要旋转我所拥有的东西。我发现一个简单的解决方案是:

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();

无论如何 - 它可能不是特别优雅,但它是将一个特定元素旋转到画布上的简单方法。

Look at all those rotated elements!

© www.soinside.com 2019 - 2024. All rights reserved.