简体   繁体   中英

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)...

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:

 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. 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); 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).

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!

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. 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. In the below example I key off of 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();
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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