保存状态
画布'save()
并且restore()
根本与画布中的像素无关。Save()
仅保存当前笔颜色、填充颜色、变换、缩放、旋转等 - 仅参数值,而不是实际像素数据。
因此,restore()
只会将这些参数值恢复到以前的值。
canvas 元素是被动的,这意味着它只保存您在屏幕上看到的像素。它不会保留任何内容的备份,因此如果您更改其大小、重新调整浏览器窗口大小或在浏览器中打开导致其清除的对话框,您将需要自己更新画布。
这也适用于更改参数值(例如比例)时。画布上的任何内容都不会更改设置新值。唯一发生的事情是您的下一次绘制将使用这些参数值进行绘制(换句话说:如果您应用旋转,则不会旋转,但您绘制的下一个将旋转)。
在现有图像上绘图
由于您需要维护内容,这也意味着您需要存储绘制的图像以及绘制的内容。
例如,当您绘制线条时,您需要将每个笔划记录到数组中。当画布需要更新(即缩放)时,您首先以新的比例重绘原始图像,然后用线条遍历数组并重新渲染它们。
点,矩形,圆和你有什么都是一样的。
将画布视为您在其他地方存储的内容(图像对象、数组、对象)的快照。画布只是该数据的视口。
我建议这样存储:
var backgroundImage; //reference to your uploaded image
var renderStack = []; //stores all drawing objects (see below)
//example generic object to hold strokes, shapes etc.
function renderObject() {
this.type = 'stroke'; //or rectangle, or circle, or dot, ...
this.x1;
this.y1;
this.x2;
this.y2;
this.radius;
this.penWidth;
this.penColor;
this.fillColor;
this.points = [];
//... extend as you need or use separate object for each type
}
然后当您绘制笔画(伪)时:
var currentRenderObject;
function mouseDown(e) {
//get a new render object for new shape/line etc.
currentRenderObject = new renderObject();
//get type from your selected tool
currentRenderObject.type = 'stroke'; //for example
//do the normal draw operations, mouse position etc.
x =..., y = ...
}
function mouseMove(e) {
//get mouse positions, draw as normal
x = ..., y = ...
//store the points to the array, here:
//we have a line or stroke, so we push the
//values to ourpoint-array in the renderObject
currentRenderObject.points.push(x);
currentRenderObject.points.push(y);
}
function mouseUp(e) {
//when paint is done, push the current renderObject
//to our render stack
renderStack.push(currentRenderObject);
}
现在您可以进行重绘功能:
function redraw() {
clearCanvas();
drawBackgroundImage();
for(var i = 0, ro; ro = renderStack[i]; i++) {
switch(ro.type) {
case 'stroke':
//... parse through point list
break;
case 'rectangle':
//... draw rectangle
break;
...
}
}
}
function zoom(factor) {
//set new zoom, position (scale/translate if you don't
//want to do it manually). Remember that mouse coords need
//to be recalculated as well to match the zoom factor.
redraw();
}
//when canvas is scaled for some reason, or the window
canvas.onresize = windows.onresize = redraw;
这样做的好处是您也可以将渲染堆栈用作撤消/重做堆栈...
希望这有助于更好地理解画布是如何工作的。