HTML5 <canvas>
元素有一种保存状态机制,通过重复调用 cxt.save()
和 cxt.restore()
, 其中cxt
是<canvas>
的“上下文”,例如通过调用 document.getElementById('my-canvas')
获得.但是,我还没有看到一次保存/恢复到多个状态的方法。似乎<canvas>
可以访问多个状态,调用 restore
多次恢复各自的“最后”保存状态。
有没有办法在不调用 restore
的情况下跳回到“最后”状态之前?多次?另外,有没有办法通过各州“前进”?如果我们可以给每个状态一个名称,这可能会更容易做到,但如果需要,我可以使用 ID。最后它可能看起来类似于 Adobe Photoshop 的“图层”概念。
我还会采用将每个状态保存到不同变量的答案,或者可以复制上下文而无需创建全新的 <canvas>
。 .复制函数,如 angular.copy
似乎不与上下文一起工作,可能是因为它们在技术上不是对象;我相信它们继承自接口(interface)。
最后,这样有效率吗?我知道图形密集程度如何<canvas>
是,它在客户端计算机上的负担有多大。有没有比实现分层系统更好的方法来操纵上下文而不破坏 Canvas 的其他部分?
最佳答案
一些背景:
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);
关于javascript - 保存多个状态并恢复到每个状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31972587/