ZetCode

JavaScript Canvas resetTransform 教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas resetTransform 方法。此方法将当前变换矩阵重置为单位矩阵。它对于管理 Canvas 绘图中的复杂变换至关重要。

基本定义

resetTransform 方法将当前变换重置为单位矩阵。这意味着它会移除应用于 Canvas 上下文的所有缩放、旋转和平移变换。

调用时,它会将变换矩阵设置为 [[1,0,0], [0,1,0], [0,0,1]]。这等同于调用 setTransform(1,0,0,1,0,0),但更具可读性和便捷性。

基本的 resetTransform 用法

此示例演示了在应用一些变换后如何使用 resetTransform。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Apply transformations
    ctx.translate(100, 50);
    ctx.rotate(Math.PI/4);
    ctx.scale(2, 2);
    
    // Draw a rectangle with transformations
    ctx.fillStyle = 'blue';
    ctx.fillRect(0, 0, 50, 50);
    
    // Reset transformations
    ctx.resetTransform();
    
    // Draw a rectangle without transformations
    ctx.fillStyle = 'red';
    ctx.fillRect(0, 0, 50, 50);
</script>

</body>
</html>

在此示例中,我们首先向 Canvas 上下文应用平移、旋转和缩放。然后我们绘制一个被变换的蓝色矩形。

调用 resetTransform 后,我们绘制一个红色矩形,它出现在其原始位置和大小。这表明 resetTransform 清除了所有先前的变换。

嵌套变换与 resetTransform

此示例展示了如何使用 resetTransform 来管理嵌套变换。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // First transformation state
    ctx.translate(100, 100);
    ctx.fillStyle = 'blue';
    ctx.fillRect(0, 0, 50, 50);
    
    // Save state and apply new transformations
    ctx.save();
    ctx.translate(100, 0);
    ctx.rotate(Math.PI/4);
    ctx.fillStyle = 'green';
    ctx.fillRect(0, 0, 50, 50);
    
    // Reset to saved state (alternative to resetTransform)
    ctx.restore();
    ctx.fillStyle = 'red';
    ctx.fillRect(0, 0, 50, 50);
    
    // Completely reset all transformations
    ctx.resetTransform();
    ctx.fillStyle = 'orange';
    ctx.fillRect(0, 0, 50, 50);
</script>

</body>
</html>

此示例演示了 resetTransformrestore 之间的区别。restore 方法返回到保存的状态,而 resetTransform 完全重置所有变换。

我们首先应用一个平移,然后保存状态。在应用更多变换后,我们恢复到保存的状态。最后,我们使用 resetTransform 完全重置所有变换。

带动画的 resetTransform

此示例显示了如何在动画循环中使用 resetTransform。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    let angle = 0;
    
    function animate() {
        // Clear canvas
        ctx.resetTransform();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // Apply transformations
        ctx.translate(200, 150);
        ctx.rotate(angle);
        angle += 0.01;
        
        // Draw rotating rectangle
        ctx.fillStyle = 'purple';
        ctx.fillRect(-25, -25, 50, 50);
        
        requestAnimationFrame(animate);
    }
    
    animate();
</script>

</body>
</html>

在此动画示例中,我们在每个帧的开头使用 resetTransform 完全清除 Canvas。这确保没有残留的变换会影响 clearRect 操作。

重置后,我们为当前帧应用新的变换。这种模式在 Canvas 动画中很常见,以在帧之间保持干净的状态。

resetTransform 与 setTransform

此示例比较了 resetTransform 和 setTransform 用于重置矩阵。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>resetTransform vs setTransform</title>
</head>
<body>

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Apply transformations
    ctx.translate(100, 50);
    ctx.scale(2, 2);
    
    // Method 1: Using resetTransform
    ctx.resetTransform();
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 50, 50);
    
    // Apply transformations again
    ctx.translate(100, 50);
    ctx.scale(2, 2);
    
    // Method 2: Using setTransform
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.fillStyle = 'red';
    ctx.fillRect(50, 50, 50, 50);
</script>

</body>
</html>

此示例演示了 resetTransformsetTransform(1,0,0,1,0,0) 在功能上是等效的。这两种方法都将变换矩阵重置为单位矩阵。

resetTransform 方法比等效的 setTransform 调用更具可读性且易于记忆。它的引入是为了简化这个常见的操作。

复杂的变换管理

此示例展示了 resetTransform 如何帮助管理复杂的变换场景。

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

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

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    function drawHouse(x, y, color) {
        ctx.save();
        ctx.translate(x, y);
        
        // House base
        ctx.fillStyle = color;
        ctx.fillRect(0, 0, 100, 80);
        
        // Roof
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(50, -40);
        ctx.lineTo(100, 0);
        ctx.closePath();
        ctx.fill();
        
        // Door
        ctx.resetTransform();
        ctx.translate(x, y);
        ctx.fillStyle = 'brown';
        ctx.fillRect(40, 40, 20, 40);
        
        ctx.restore();
    }
    
    drawHouse(50, 100, 'lightblue');
    drawHouse(200, 150, 'pink');
    drawHouse(350, 80, 'lightgreen');
</script>

</body>
</html>

在这个复杂的示例中,我们使用 resetTransform 来独立管理绘图的不同部分。房屋绘图函数使用变换进行定位,但为某些元素重置它们。

屋顶相对于初始平移绘制,而门使用 resetTransform 从基本位置重新开始。这表明 resetTransform 可以精确控制变换状态。

来源

MDN Canvas resetTransform 文档

在本文中,我们探讨了 resetTransform 方法及其在管理 Canvas 变换中的用法。此方法对于在复杂的绘图操作和动画中保持控制至关重要。

作者

我叫 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 JS Canvas 教程