ZetCode

JavaScript Canvas 旋转教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas 旋转方法。旋转是一种基本的变换,它允许您围绕某个点旋转形状和路径。掌握旋转对于创建动态图形至关重要。

基本定义

Canvas 旋转是指围绕指定点(通常是原点)旋转形状的过程。旋转角度以弧度为单位测量,正值表示顺时针旋转。

主要的旋转方法是 rotate(angle),它将旋转变换应用于 canvas。旋转会影响所有后续的绘图操作,直到 canvas 状态被恢复。

基本旋转示例

此示例演示了如何在 canvas 上旋转一个简单的矩形。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic Canvas Rotation</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Save the default state
    ctx.save();
    
    // Rotate 45 degrees (convert to radians)
    ctx.rotate(Math.PI / 4);
    
    // Draw a rectangle
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 50);
    
    // Restore the default state
    ctx.restore();
</script>

</body>
</html>

在这个基本示例中,我们首先保存默认的 canvas 状态。然后,我们使用 rotate 方法将 canvas 旋转 45 度(π/4 弧度)。

矩形在旋转后绘制,因此它看起来是旋转的。最后,我们使用 restore 将 canvas 恢复到其原始状态。

围绕某个点旋转

此示例展示了如何围绕特定点旋转形状。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Rotation Around Point</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const centerX = 150;
    const centerY = 100;
    const angle = Math.PI / 6; // 30 degrees
    
    ctx.save();
    
    // Move to center point, rotate, then move back
    ctx.translate(centerX, centerY);
    ctx.rotate(angle);
    ctx.translate(-centerX, -centerY);
    
    // Draw rectangle
    ctx.fillStyle = 'red';
    ctx.fillRect(centerX - 50, centerY - 25, 100, 50);
    
    ctx.restore();
    
    // Mark the rotation point
    ctx.fillStyle = 'black';
    ctx.beginPath();
    ctx.arc(centerX, centerY, 5, 0, Math.PI * 2);
    ctx.fill();
</script>

</body>
</html>

要围绕特定点旋转,我们首先平移到该点,然后旋转,再平移回来。这种技术对于受控旋转至关重要。

示例将一个矩形围绕其中心点 (150,100) 旋转 30 度。我们还绘制了一个小的黑点来标记旋转中心。

动画旋转

此示例演示了使用旋转进行的平滑动画。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Animated Rotation</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    let angle = 0;
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    
    function draw() {
        // Clear canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        ctx.save();
        ctx.translate(centerX, centerY);
        ctx.rotate(angle);
        ctx.translate(-centerX, -centerY);
        
        // Draw triangle
        ctx.fillStyle = 'green';
        ctx.beginPath();
        ctx.moveTo(centerX, centerY - 50);
        ctx.lineTo(centerX - 30, centerY + 40);
        ctx.lineTo(centerX + 30, centerY + 40);
        ctx.closePath();
        ctx.fill();
        
        ctx.restore();
        
        // Increase angle for next frame
        angle += 0.02;
        if (angle > Math.PI * 2) angle = 0;
        
        // Request next animation frame
        requestAnimationFrame(draw);
    }
    
    // Start animation
    draw();
</script>

</body>
</html>

此示例使用 requestAnimationFrame 方法创建了一个持续旋转的三角形,以实现平滑的动画效果。

每帧旋转角度都会略微增加,从而产生动画效果。在每次重绘之前清除 canvas 以防止出现拖影。

多个旋转对象

此示例展示了如何绘制具有不同旋转的多个对象。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Multiple Rotated Objects</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    function drawRotatedRect(x, y, width, height, angle, color) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(angle);
        
        ctx.fillStyle = color;
        ctx.fillRect(-width/2, -height/2, width, height);
        
        ctx.restore();
    }
    
    // Draw multiple rotated rectangles
    drawRotatedRect(100, 100, 80, 40, Math.PI/6, 'blue');
    drawRotatedRect(200, 150, 60, 60, Math.PI/4, 'red');
    drawRotatedRect(300, 100, 100, 30, Math.PI/3, 'green');
</script>

</body>
</html>

在这里,我们创建了一个名为 drawRotatedRect 的辅助函数,该函数会在其中心点绘制一个旋转的矩形。该函数在内部处理平移和旋转。

然后,我们使用此函数以不同的位置、旋转角度和颜色绘制三个矩形。这展示了可重用的旋转代码。

将旋转与其他变换相结合

此示例将旋转与缩放和平移相结合。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Combined Transformations</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw original shape (reference)
    ctx.fillStyle = 'rgba(200, 200, 200, 0.5)';
    ctx.fillRect(100, 100, 100, 50);
    
    // Apply transformations
    ctx.save();
    ctx.translate(200, 150);  // Move origin
    ctx.rotate(Math.PI / 3);  // Rotate 60 degrees
    ctx.scale(1.5, 1.5);      // Scale up
    
    // Draw transformed shape
    ctx.fillStyle = 'rgba(255, 0, 0, 0.7)';
    ctx.fillRect(-50, -25, 100, 50); // Draw centered on new origin
    
    ctx.restore();
</script>

</body>
</html>

此示例演示了变换的顺序应用:先平移,然后旋转,最后缩放。顺序很重要。

我们绘制一个半透明的灰色矩形作为参考,然后绘制一个变换过的红色矩形。变换过的矩形被缩放、旋转和移动。

来源

MDN Canvas 旋转文档

在本文中,我们探索了在 HTML canvas 上旋转形状的各种技术。掌握旋转对于在 Web 应用程序中创建动态和交互式图形至关重要。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 JS Canvas 教程