ZetCode

JavaScript Canvas 翻译教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas translate 方法。此方法将画布原点移动到新位置,影响所有后续绘图操作。掌握翻译对于复杂的绘图至关重要。

基本定义

Canvas 翻译会将画布的原点 (0,0) 移动到新的位置。这会通过偏移坐标来影响所有后续的绘图操作。translate 方法不会移动现有绘图。

translate(x, y) 方法接受两个参数:水平 (x) 和垂直 (y) 偏移值。正值向右/向下移动,负值向左/向上移动,相对于当前原点。

基本翻译

此示例演示了如何翻译画布原点并绘制一个矩形。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw at original origin (0,0)
    ctx.fillStyle = 'red';
    ctx.fillRect(0, 0, 50, 50);
    
    // Translate origin to (100,50)
    ctx.translate(100, 50);
    
    // Draw at new origin (0,0 is now at 100,50)
    ctx.fillStyle = 'blue';
    ctx.fillRect(0, 0, 50, 50);
</script>

</body>
</html>

此示例首先在原始原点 (0,0) 处绘制一个红色正方形。然后我们将原点平移到 (100,50),并在新原点处绘制一个蓝色正方形。

蓝色正方形出现在画布上的 (100,50) 位置,因为我们在翻译后将其绘制在 (0,0) 处。翻译会影响所有后续绘图。

多次翻译

此示例展示了多次翻译如何累积其效果。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // First translation
    ctx.translate(50, 50);
    ctx.fillStyle = 'red';
    ctx.fillRect(0, 0, 50, 50);
    
    // Second translation (relative to first)
    ctx.translate(100, 100);
    ctx.fillStyle = 'green';
    ctx.fillRect(0, 0, 50, 50);
    
    // Third translation (relative to previous)
    ctx.translate(100, 100);
    ctx.fillStyle = 'blue';
    ctx.fillRect(0, 0, 50, 50);
</script>

</body>
</html>

此示例演示了翻译是累积的。每次调用 translate 都会相对于其当前位置移动原点,而不是相对于原始位置。

红色正方形位于 (50,50),绿色正方形位于 (150,150),蓝色正方形位于 (250,250)。每次翻译都会在前一次的基础上叠加,从而形成对角线图案。

带旋转的翻译

此示例将翻译与旋转结合起来,以创建旋转图案。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';
    
    for (let i = 0; i < 12; i++) {
        ctx.save();
        
        // Move origin to center
        ctx.translate(200, 200);
        
        // Rotate around new origin
        ctx.rotate(i * Math.PI / 6);
        
        // Draw rectangle (offset from center)
        ctx.fillRect(100, -10, 100, 20);
        
        ctx.restore();
    }
</script>

</body>
</html>

此示例使用翻译和旋转创建圆形图案的矩形。我们首先平移到中心,然后旋转,然后绘制。

saverestore 方法用于保存和恢复变换状态。这确保每个矩形在变换之前都从相同的初始状态开始。

嵌套翻译

此示例演示了用于分层绘图的嵌套翻译。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Nested Translations</title>
</head>
<body>

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Main body
    ctx.translate(250, 200);
    drawRobot(ctx, 0, 0, 'blue');
    
    // Left arm
    ctx.save();
    ctx.translate(-50, -30);
    drawRobot(ctx, 0, 0, 'red');
    ctx.restore();
    
    // Right arm
    ctx.save();
    ctx.translate(50, -30);
    drawRobot(ctx, 0, 0, 'green');
    ctx.restore();
    
    function drawRobot(ctx, x, y, color) {
        ctx.fillStyle = color;
        ctx.fillRect(x - 30, y - 50, 60, 100);
        ctx.fillRect(x - 50, y - 30, 20, 60);
        ctx.fillRect(x + 30, y - 30, 20, 60);
    }
</script>

</body>
</html>

此示例创建了一个简单的机器人图形,包含一个主身体和两条手臂。每个部分都根据其自己的局部坐标系进行绘制。

主体绘制在中心。手臂使用嵌套翻译相对于身体进行绘制。saverestore 维护变换堆栈。

带动画的翻译

此示例展示了如何在动画循环中使用翻译。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Animation with Translation</title>
</head>
<body>

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    let x = 0;
    
    function animate() {
        // Clear canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // Save current state
        ctx.save();
        
        // Translate to current position
        ctx.translate(x, 150);
        
        // Draw square
        ctx.fillStyle = 'purple';
        ctx.fillRect(-25, -25, 50, 50);
        
        // Restore state
        ctx.restore();
        
        // Update position
        x += 2;
        if (x > canvas.width) x = -50;
        
        // Continue animation
        requestAnimationFrame(animate);
    }
    
    animate();
</script>

</body>
</html>

此示例通过翻译动画化一个在画布上移动的正方形。正方形的位置在每一帧都会更新,并且翻译会移动它。

我们使用 saverestore 来隔离翻译效果。动画循环使用 requestAnimationFrame 无限期地继续。

来源

MDN Canvas translate 文档

在本文中,我们探讨了使用 Canvas 中的 translate 方法的各种技术。掌握翻译对于 JavaScript 中复杂的绘图、动画和游戏开发至关重要。

作者

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

列出 所有 JS Canvas 教程