一些背景:
context.save 和 context.restore 保存和恢复上下文状态。上下文状态包括样式、转换、合成等。
.save 会将当前状态推送到堆栈顶部。 .restore 将从堆栈顶部弹出最后添加的状态。因此,它们充当后进先出的状态堆栈。
您可以执行多个.save,这会将多个状态推送到堆栈上。然后,您可以通过执行多个.restore 将多个状态从堆栈中弹出。
由于.save 将保存所有上下文状态,保存和恢复是相对昂贵的操作。
多次保存/恢复的示例:
context.fillStyle='red';
context.fillRect(0,0,10,10); // red rectangle
context.save(); // fillStyle=='red'
context.fillStyle='blue'; // fillStyle='blue'
context.fillRect(0,0,10,10); // blue rectangle
context.save(); // fillStyle=='blue'
context.fillStyle='green'; // fillStyle=='green'
context.fillRect(0,0,10,10); // green rectangle
context.restore(); // fillStyle='blue';
context.fillRect(0,0,10,10); // blue rectangle
context.restore(); // fillStyle='red'
context.fillRect(0,0,10,10); // red rectangle
答案#1:不,如果不执行多次恢复,就无法恢复到之前保存的状态。状态保存在堆栈中,因此与状态数组不同,您不能“跳转”到状态[2]。
答案#2:在实践中,更常见的是不使用保存/恢复,而是使用 javascript 对象来存储所需的最少状态信息。
例如:
// put various fillStyles in a fills object
var fills={};
fills.red='red';
fills.green='green';
fills.blue='blue';
// create a function that draws a rect with specified fillStyle
function styledRect(x,y,w,h,fill){
var priorFill=context.fillStyle;
context.fillStyle=fill;
context.fillRect(x,y,w,h);
context.fillStyle=priorFill;
}
// use the fills object to control the fillStyle "state"
styledRect(0,0,10,10,fills.red);
更复杂的“状态”对象可能如下所示:
buttonStyles={};
buttonStyles.normal={ font:'12px verdana', fill:'black' };
buttonStyles.warning={font:'12px italic verdana', fill:'orange' };
buttonStyles.danger={ font:'14px italic verdana', fill:'red' };
// example usage
someButtonDrawingFunction("You're in danger!",buttonStyles.danger);