Ton*_*ich 17 html5 html5-canvas
此页面显示HTML5画布中的一些动画.如果查看滚动条的来源,则会在清除矩形并在动画后恢复它时保存上下文.如果我用另一个ctx.clearRect(0, 0, can.width, can.height语句替换restore 语句,则无效.我认为恢复正在恢复已清除的矩形,但它似乎恢复了更多信息.下一帧需要的额外信息是什么?
我不是在寻找保存和恢复的HTML5教科书定义,但我想了解这个具体示例中为什么需要它们.
UPDATE
在我不想得到save()和restore()的定义的问题中我已经特别提到的答案是令人沮丧的.我已经知道Save()保存上下文的状态,Restor()e恢复它.我的问题很具体.为什么在将所有Save do保存为空画布时,以示例方式使用restore().为什么还原空白画布与清除它不一样?
Nor*_*ard 39
画布状态不是它所绘制的.它是一堆属性,用于定义用于绘制下一个东西的工具的当前状态.
Canvas是一种立即模式位图.像MS Paint一样.一旦它在那里,它就在那里,所以没有必要"保存"当前的图像数据,因为这就像保存整个JPEG一样,每次你做出改变,每一帧......
...不,你保存的状态是指示用于绘制NEXT事物的坐标方向,尺寸比例,颜色等的状态(以及之后的所有事情,直到您手动更改这些值).
var canvas = document.createElement("canvas"),
easel = canvas.getContext("2d");
easel.fillStyle = "rgb(80, 80, 120)";
easel.strokeStyle = "rgb(120, 120, 200)";
easel.fillRect(x, y, width, height);
easel.strokeRect(x, y, width, height);
easel.save(); // stores ALL current status properties in the stack
easel.rotate(degrees * Math.PI / 180); // radians
easel.scale(scale_X, scale_Y); // any new coordinates/dimensions will now be multiplied by these
easel.translate(new_X, new_Y); // new origin coordinates, based on rotated orientation, multiplied by the scale-factor
easel.fillStyle = "gold";
easel.fillRect(x, y, width, height); // completely new rectangle
// origin is different, and the rotation is different, because you're in a new coordinate space
easel.clearRect(0, 0, width, height); // not even guaranteed to clear the actual canvas, anymore
easel.strokeRect(width/2, height/2, width, height); // still in the new coordinate space, still with the new colour
easel.restore(); // reassign all of the previous status properties
easel.clearRect(0, 0, width, height);
Run Code Online (Sandbox Code Playgroud)
假设你在堆栈深处只有一个状态变化,那么最后一行,现在你的画布'之前的状态已经恢复,应该已经成功地清除了自己(尽管有亚像素的恶作剧).
正如你所看到的,它与擦除画布非常相似.
事实上,它完全没有与擦除它有关.
它与想要画一些东西,做基本的轮廓和清晰的颜色/样式,然后在顶部手动写入较小细节的颜色,然后手动将所有样式写回以前的方式,回到下一个物体,然后继续扫描......
相反,保存将被重用的一般状态,为较小的细节创建新状态,并返回到一般状态,而不必每次都对其进行硬编码,或者编写setter函数以在画布上设置常用值以及(重置比例/旋转/仿射变换/颜色/字体/线宽/基线对齐/等).
在你的确切例子中,如果你正在注意,你会发现唯一改变的是价值step.
他们为画布设置了一堆值的状态(颜色/字体/等).
然后他们救了.那么,他们节省了什么?
你看起来不够深.他们实际上保存了默认翻译(即原始世界空间中的原点= 0,0).
但你没有看到他们定义它?
那是因为它被定义为默认值.
然后他们增加第1步像素(实际上,他们首先执行此操作,但在第一次循环之后无关紧要 - 请留在我这里).
然后他们为0,0设置了一个新的原点(即:从现在开始,当他们键入时0,0,新的原点将指向画布上完全不同的位置).
该原点等于x是画布的正中间,y等于当前步(即:像素1或像素2等等......以及为什么从0开始到1开始之间的差异确实不存在没问题.
然后他们做了什么?
他们恢复了.
那么,他们恢复了什么?
......好吧,他们改变了什么?
他们将原点恢复为0,0
为什么?
好吧,如果他们没有,会发生什么?
如果画布是500px x 200px,它在我们当前的屏幕空间中从0开始......那太好了...
然后他们把它翻译成宽度/ 2,1
好吧,所以现在当他们要求画画时在0,0的文本,他们实际上将绘制在250,1
精彩.但下次会发生什么?
现在他们按宽度/ 2翻译,2
你认为,那很好......对于0,0的抽奖调用将发生在250,2,因为他们已经将它设置为清除数字: canvas.width/2,2
不.因为根据我们的屏幕,当前0,0实际上是250,1.一个翻译与之前的翻译有关...
...所以现在你告诉画布开始它的当前坐标'0,0然后向左转250,向下2.
根据屏幕(就像一个窗口,看着地图,而不是地图,本身)我们现在向右500px,距离我们开始的地方有3个像素......而且只有一个框架已经过去了.
因此,在设置新坐标之前,它们将地图的坐标恢复为与屏幕坐标相同的原点(以及旋转相同,比例和倾斜等等).
正如你可能猜到的那样,通过观察,现在,你可以看到文本实际上应该从上到下移动.不对,就像页面上说的那样......
为什么这样?
当绘图命令在函数中给出一个x并且y正确的时候,为什么要改变绘图上下文的坐标系呢?
如果你想在画布上画一幅画,你知道它的高度和宽度,以及你想要左上角的位置,为什么你不能这样做:
easel.drawImage(myImg, x, y, myImg.width, myImg.height);
Run Code Online (Sandbox Code Playgroud)
好吧,你可以.
你完全可以做到这一点.什么都没有阻止你.
事实上,如果你想让它放大在屏幕上,你可以只更新x和y一个计时器,并收工.
但是,如果你正在画一个游戏角色呢?如果这个角色戴着帽子,戴着手套的手和大靴子,所有这些东西都与角色分开了怎么办?
所以首先你要说"好吧,他站在世界的x和y,所以x加上他的手与他的身体相关的是x + body.x - hand.x ......或者是那个加号. .."
...现在你已经把他所有的部分都画了一个看起来像是满是5年级数学作业的笔记本.
相反,你可以说:"他在这里.设置我的坐标,以便0,0正好在我的家伙中间".现在您的绘制调用就像"我的右手是身体右侧6个像素,左手是左侧3个像素"一样简单.
当你完成绘制角色时,可以将原点设置回0,0然后可以绘制下一个角色.或者,如果你想尝试它,你可以根据从一个到另一个的增量从那里翻译到下一个字符的原点(这将为每个翻译节省一个函数调用).然后,如果你只在整个时间(原始状态)保存状态,最后,你可以通过调用返回到0,0 .restore.
上下文 save() 保存诸如变换颜色之类的东西。然后您可以更改上下文并将其恢复为与保存时相同的上下文。它的工作方式类似于堆栈,因此您可以将多个画布状态推入堆栈并恢复它们。 http://html5.litten.com/understanding-save-and-restore-for-the-canvas-context/
| 归档时间: |
|
| 查看次数: |
15880 次 |
| 最近记录: |