应用更改后,使用图像背景保存未缩放的画布

时间:2013-06-17 11:59:28

标签: html5 image canvas editor

我有一个很大的问题,它差不多一周试图让它工作所以任何帮助我真的很感激 - 我试图在html5中创建一个简单的图像编辑器,所以我上传一个图像,加载到画布然后在上面画画 -

我也希望能够放大和缩小 - 只是我无法弄清楚我应该如何保存画布状态 - 对于paint mouseevents我正在使用一个保存canvas.toDataUrl的数组,但是这个将仅保存在画布中可见的内容,仅保存缩放图像的一部分,而不是整个 -

如果有人知道如何将画布与画布一起展开并将其保存在堆栈中,我可以将其保存到其他绘画活动中,我会非常感激!感谢

1 个答案:

答案 0 :(得分:0)

保存状态

画布“save()restore()与画布中的像素完全无关。 Save()仅保存当前的笔颜色,填充颜色,变换,缩放,旋转等 - 仅参数值,而不是实际的像素数据。

因此,restore()只会将这些参数值恢复为之前的参数值。

canvas元素是被动的,这意味着它只保存您在屏幕上看到的像素。它不会保留任何内容的备份,因此如果您更改其大小,重新调整浏览器窗口大小或在浏览器中打开对话框以使其清除,您将需要自己更新画布。

当您更改参数值(如比例)时,这也适用。画布上的任何内容都不会更改设置新值。唯一发生的事情就是你的下一次绘制的东西将使用这些参数值作为绘图(换句话说:如果你应用旋转什么都不会旋转,但你接下来绘制的东西将被旋转)。

在现有图像上绘图

由于您需要维护内容,这也意味着您需要存储您绘制的图像以及您绘制的内容。

绘制示例线时,需要将每个笔划记录到数组中。当画布需要更新(即缩放)时,您首先以新比例重绘原始图像,然后使用线条遍历数组并重新渲染它们。

点,矩形,圆圈和你有什么相同......

将canvas视为您在其他地方存储的内容的快照(图像对象,数组,对象)。 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;

这样做的一个好处就是你可以使用渲染堆栈作为撤销/重做堆栈......

希望这有助于更好地理解画布的工作原理。