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 教程。