简体   繁体   English

提交表单后更新和保存画布

[英]Updating and saving canvas upon form submit

I have the following code, which executes before a form is submitted. 我有以下代码,该代码在提交表单之前执行。

I'm changing an image then redrawing a canvas before saving that image. 我正在更改图像,然后在保存该图像之前重新绘制画布。

the problem I have is that it doesn't work as intended (instead it saves the image with the previous image src attribute)... 我的问题是,它无法按预期工作(相反,它使用以前的图像src属性保存图像)...

If I step through it in firebug the correct image is saved, which leads me to think there needs to be a delay before it saves.... 如果我在萤火虫中逐步浏览,则会保存正确的图像,这使我认为保存之前需要一段时间。

How do I do it? 我该怎么做?

$('#WindowForm').submit(function () {
            if (isInternal)
            {
                imgsrc = $(".externalColor.selected-color").find('img').attr("src");
                draw();

                var canvas = document.getElementById('myCanvas');

                context.drawImage(can, 0, 0)

                var dataURL = canvas.toDataURL();
                $("#ImageData").val(dataURL);
                return true;
            }

        });

Note that there is an onload in the draw method too: 注意draw方法中也有一个onload:

 var img = new Image();
 img.src = imgsrc;    
 img.onload = function () {
                    pattern = context.createPattern(img, "repeat");
                    context.fillStyle = pattern;
                    DrawContext(context);


                };

The problem is very likely that you need to wait for the image to load in your draw() function. 问题很可能是您需要等待图像加载到draw()函数中。 The best way would be to include a callback parameter in your function, so you could save after it is finished. 最好的方法是在函数中包括一个回调参数,以便在完成后可以保存。

function draw(callback){
    //...
    img.onload = (function(callback){
        return function(){
            //...create your pattern...
            callback.call();
        };
    })(callback);
}

draw(function(){ /* ...save image... */ });

You could also use something like setTimeout(function(){ /*...save image...*/ }, 1); 您还可以使用类似setTimeout(function(){ /*...save image...*/ }, 1); but this isn't the best solution. 但这不是最好的解决方案。

I'd approach it like this: 我会这样处理:

$( 'form' ).on(
    'submit',
    function( evt ) {

        var form = $( this );

        evt.preventDefault(); // prevent the form submission

        // ...do stuff...

        // delay the submission
        window.setTimeout(
            function() {

                form.off( 'submit' ); // remove this event handler
                form.submit(); // manually submit the form

            },
            500 // or whatever
        );

    }
);

This basically stops the form from being submitted until everything is sorted, then manually submits it. 这基本上阻止了表单的提交,直到所有内容都进行了排序,然后手动提交。 You might want to combine this with @Evilzebra's answer and stick the timeout function in an onload event for the created image, however the basic principles will be the same (prevent submission, then manually submit once ready). 您可能希望将其与@Evilzebra的答案结合使用,并将超时功能保留在所创建图像的onload事件中,但是基本原理是相同的(防止提交,然后在准备好后手动提交)。

NB you need to unbind the event handler before the manual submit, or the submit event will fire again and just keep running in a loop! 注意,您需要在手动提交之前取消绑定事件处理程序,否则Submit事件将再次触发并保持循环运行!

Looking through your code I think I understand what you're trying to do, and why its not working. 查看您的代码,我想我了解您正在尝试做的事情,以及为什么它不起作用。 First off I think your example code has some errors that shouldn't be there. 首先,我认为您的示例代码存在一些错误,这些错误不应该存在。 I'm going to assume that imgsrc should be img.src at which point your making an asynchronous call to load a new image, which most likely won't be done until after you've competed the rest of this function. 我将假设imgsrc应该是img.src ,此时您进行异步调用以加载新图像,这很可能要等到您完成了该功能的其余部分之后才能完成。 A quick and easy way to remedy this is to create a flag that lets the img.onload know if it should be saving the image or not. 解决此问题的快速简便的方法是创建一个标志,让img.onload知道是否应保存图像。 In the below example I key off of isInternal 在下面的示例中,我键入了isInternal

$('#WindowForm').submit(function (e) {
    if (isInternal)
    {
        e.preventDefault();
        imgsrc = $(".externalColor.selected-color").find('img').attr("src");
        // this will then cause the img.onload to fire
    };
});

function pleaseSubmitMe(){
    draw();
    var canvas = document.getElementById('myCanvas');

    context.drawImage(can, 0, 0)
    var dataURL = canvas.toDataURL();
    $("#ImageData").val(dataURL);
    // alright now that thats done, lets submit this bad boy
    isInternal= false; // we need to set this to false so we actually try submitting
    $('#WindowForm').submit();
}

img.onload = function () {
    pattern = context.createPattern(img, "repeat");
    context.fillStyle = pattern;
    DrawContext(context);
    // if I'm Internal lets send this image to be submitted
    if(isInternal){
        pleaseSubmitMe();
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM