JavaScript Canvas 保存教程
最后修改于 2025 年 4 月 3 日
在本文中,我们将探讨 JavaScript 中的 Canvas 保存和恢复方法。这些方法对于在处理复杂的 Canvas 图形时管理绘图状态至关重要。掌握状态管理是高效 Canvas 编程的关键。
基本定义
Canvas 的 `save()` 和 `restore()` 方法用于管理绘图状态堆栈。`save()` 方法将当前状态推入堆栈,而 `restore()` 方法从堆栈中弹出最近保存的状态。
绘图状态包括变换、样式、剪裁路径等。这些方法允许进行临时更改,而不会影响后续的绘图。它们在复杂的绘图操作中特别有用。
基本的保存和恢复
此示例演示了保存和恢复方法的_基本用法_。
<!DOCTYPE html>
<html>
<head>
<title>Basic Canvas Save/Restore</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Original state
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 100, 50);
// Save state
ctx.save();
// Modify state
ctx.fillStyle = 'red';
ctx.fillRect(130, 10, 100, 50);
// Restore state
ctx.restore();
// Uses original blue color
ctx.fillRect(250, 10, 100, 50);
</script>
</body>
</html>
此示例展示了 `save()` 和 `restore()` 如何影响绘图状态。我们首先绘制一个蓝色矩形,然后使用 `save()` 保存当前状态。
在将填充样式更改为红色并绘制另一个矩形后,我们调用 `restore()` 返回到先前的状态。第三个矩形使用了原始的蓝色。
嵌套保存和恢复
此示例演示了嵌套多个保存和恢复操作。
<!DOCTYPE html>
<html>
<head>
<title>Nested Save/Restore</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Initial state
ctx.fillStyle = 'black';
ctx.fillRect(10, 10, 100, 50);
// First save
ctx.save();
ctx.fillStyle = 'blue';
ctx.fillRect(130, 10, 100, 50);
// Second save
ctx.save();
ctx.fillStyle = 'red';
ctx.fillRect(250, 10, 100, 50);
// First restore (back to blue)
ctx.restore();
ctx.fillRect(10, 80, 100, 50);
// Second restore (back to black)
ctx.restore();
ctx.fillRect(130, 80, 100, 50);
</script>
</body>
</html>
此示例展示了保存和恢复操作如何以堆栈(LIFO - 后进先出)顺序工作。我们首先保存黑色填充状态,然后更改为蓝色并再次保存。
更改为红色并绘制后,我们执行两次恢复。第一次恢复返回到蓝色状态,第二次恢复返回到最初的黑色状态。这演示了状态管理的嵌套性质。
结合变换的保存/恢复
此示例展示了保存和恢复如何与 Canvas 变换一起使用。
<!DOCTYPE html>
<html>
<head>
<title>Save/Restore with 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 rectangle
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 50);
// Save state
ctx.save();
// Apply transformation
ctx.translate(100, 100);
ctx.rotate(Math.PI/4);
ctx.fillStyle = 'red';
ctx.fillRect(50, 50, 100, 50);
// Restore state
ctx.restore();
// Draw with original transformation
ctx.fillStyle = 'green';
ctx.fillRect(200, 50, 100, 50);
</script>
</body>
</html>
此示例演示了保存和恢复不仅影响样式,还影响变换。我们首先在默认状态下绘制一个蓝色矩形。
保存后,我们应用平移和旋转变换并绘制一个红色矩形。恢复后,绘制的绿色矩形_不_受这些变换的影响,这表明状态已正确恢复。
结合剪裁的保存/恢复
此示例演示了如何将保存和恢复与剪裁路径一起使用。
<!DOCTYPE html>
<html>
<head>
<title>Save/Restore with Clipping</title>
</head>
<body>
<canvas id="myCanvas" width="400" height="300"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw without clipping
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 300, 200);
// Save state
ctx.save();
// Create clipping path
ctx.beginPath();
ctx.arc(200, 150, 100, 0, Math.PI * 2);
ctx.clip();
// Draw with clipping
ctx.fillStyle = 'red';
ctx.fillRect(50, 50, 300, 200);
// Restore state (removes clipping)
ctx.restore();
// Draw without clipping again
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
</script>
</body>
</html>
此示例展示了剪裁路径如何受到保存和恢复的影响。我们首先绘制一个没有剪裁的蓝色矩形。然后我们保存状态。
创建圆形剪裁路径后,我们绘制一个仅在剪裁区域内可见的红色矩形。恢复后,绘制的绿色矩形_没有_剪裁,这表明状态已正确恢复。
高级状态管理
此示例展示了具有多个属性的复杂状态管理。
<!DOCTYPE html>
<html>
<head>
<title>Advanced State Management</title>
</head>
<body>
<canvas id="myCanvas" width="500" height="400"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Set initial styles
ctx.fillStyle = 'blue';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.font = '20px Arial';
// Draw with initial state
ctx.fillRect(50, 50, 100, 50);
ctx.strokeRect(50, 50, 100, 50);
ctx.fillText('Initial', 50, 130);
// Save state
ctx.save();
// Modify multiple properties
ctx.fillStyle = 'red';
ctx.strokeStyle = 'green';
ctx.lineWidth = 5;
ctx.font = 'italic 16px Times';
// Draw with modified state
ctx.fillRect(200, 50, 100, 50);
ctx.strokeRect(200, 50, 100, 50);
ctx.fillText('Modified', 200, 130);
// Save nested state
ctx.save();
// Modify again
ctx.fillStyle = 'yellow';
ctx.strokeStyle = 'purple';
ctx.lineWidth = 1;
// Draw with second modified state
ctx.fillRect(350, 50, 100, 50);
ctx.strokeRect(350, 50, 100, 50);
ctx.fillText('Nested', 350, 130);
// Restore to first modified state
ctx.restore();
ctx.fillRect(200, 200, 100, 50);
ctx.strokeRect(200, 200, 100, 50);
// Restore to initial state
ctx.restore();
ctx.fillRect(50, 200, 100, 50);
ctx.strokeRect(50, 200, 100, 50);
</script>
</body>
</html>
这个综合示例演示了保存和恢复如何同时影响多个绘图状态属性。我们在不同级别修改了填充、描边、线宽和字体属性。
该示例展示了嵌套状态管理,包含两次保存操作和相应的恢复。每次恢复都会返回到保存的确切状态,包括所有样式属性和变换。
来源
在本文中,我们探索了使用保存和恢复方法管理 Canvas 状态的各种技术。这些强大的工具对于 Web 应用程序中复杂的 Canvas 绘图和动画至关重要。
作者
列出 所有 JS Canvas 教程。