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

IT技术 javascript animation html canvas
2021-02-16 14:50:58

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

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

到目前为止,我所看到的只是展示如何旋转整个画布的文章和示例。现在,我猜我必须旋转画布,绘制图像,然后在绘制第二幅图像之前将画布旋转回其原始位置。如果是这样,那就让我知道吧!我只是觉得还有另一种方式。

任何人有任何想法?

提前致谢!

6个回答

我在最近的一个项目中遇到了同样的问题(我把旋转的外星人踢得到处都是)。我只是使用了这个不起眼的函数,它做同样的事情,可以像 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();
}

是的,我的第一个答案!

惊人!谢谢!
2021-04-30 14:50:58
这应该内置到画布中。完美运行。感谢你的分享!
2021-05-02 14:50:58
这个现在应该真正标记为答案。太糟糕了,SO 不允许在以后选择较新的答案作为答案。也许这是应该考虑的事情,因为技术发生了变化,人们会提出更新更正确的答案。
2021-05-03 14:50:58
如果您一次又一次地旋转它,它是否有可能导致背景质量下降?
2021-05-05 14:50:58
不会使用saverestore节省重置的时间和麻烦吗?
2021-05-10 14:50:58

不幸的是,在 HTML5 画布元素中,您不能旋转单个元素。

动画就像在 MS Paint 中绘图:你画一些东西,制作一个屏幕......使用橡皮擦去除一些东西,绘制不同的东西,制作一个屏幕......在上面绘制其他东西,制作一个屏幕......等等。

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

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

ctx.save();
ctx.rotate(0.17);
// draw your object
ctx.restore();
我知道这已经得到了回答,但是对于通过 Google 或搜索解决此问题的任何人,请记住这一基本原则:双缓冲是一种常见做法,您可以在屏幕外进行所有渲染并将整个图像复制到实际可见的画布上作为一个图像。它特别有助于动画。Artiom(等人),请记住,即使像 Java 这样的语言也被设计为在某些内容更新时完全重绘每一帧。因此,尽管稍微复杂一些,但它基于扎实的原则并有其好处。完全值得学习和实施。
2021-04-17 14:50:58
是的,我知道......当编写更复杂的动画时,这个问题变得更大,因为你必须用每一帧从头开始重新绘制整个画布:)
2021-04-24 14:50:58
嗯..这取决于你想要做什么。如果一般背景是绿色的,那就fillRect()更合适了:)
2021-04-26 14:50:58
建议您在答案中替换fillRect()clearRect()
2021-05-07 14:50:58
无赖!我想那是必须的,Artiom!感谢您的回复!
2021-05-09 14:50:58

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

            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);
        <canvas width="1280" height="720" id="pageCanvas">
            You do not have a canvas enabled browser
        </canvas>

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

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

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

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

旋转呢?你从来没有提到过。
2021-05-04 14:50:58
这正是我需要知道的,谢谢!也许如果你把轮换部分,你会得到更多的选票..
2021-05-08 14:50:58

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

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