首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应用更改后,使用图像背景保存未缩放的画布

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

Stack Overflow用户
提问于 2013-06-17 19:59:28
回答 1查看 235关注 0票数 0

我有一个很大的问题,我花了将近一周的时间试图让它工作,所以我真的很感激任何帮助-我正在尝试用html5创建一个简单的图像编辑器,所以我上传了一张图像,加载到画布上,然后在上面作画-

我还希望能够放大和缩小-只是我不知道如何保存画布状态-我正在使用一个保存canvas.toDataUrl的数组来保存绘制鼠标事件,但这个数组将只保存它在画布中可见的内容,只保存缩放图像的一部分,而不是整个图像-

如果有人知道如何将画布与其上的绘画一起取消缩放,并将其保存在堆栈中,以便我可以在其他绘画事件中检索它,我将非常感谢!谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-18 10:30:41

保存状态

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

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

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

这也适用于更改参数值时。画布上的任何东西都不会改变设置一个新值。唯一发生的事情是,您的下一次绘制将使用这些参数值进行绘制(换句话说:如果您应用旋转,则所有内容都不会旋转,但您绘制的下一个对象将被旋转)。

在现有图像上绘制

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

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

点、矩形、圆和你有的东西也是一样的。

将canvas看作是您在其他地方存储的内容(图像对象、数组、对象)的快照。Canvas只是数据的一个视图端口。

我建议这样存储:

代码语言:javascript
复制
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
}

当您随后绘制笔划(伪)时:

代码语言:javascript
复制
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);
}

现在,您可以创建一个重画函数:

代码语言:javascript
复制
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;

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

希望这有助于更好地理解canvas是如何工作的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17146985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档